summaryrefslogtreecommitdiffstats
path: root/src/lib/kStuff/include/k
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:21:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:21:29 +0000
commit29cd838eab01ed7110f3ccb2e8c6a35c8a31dbcc (patch)
tree63ef546b10a81d461e5cf5ed9e98a68cd7dee1aa /src/lib/kStuff/include/k
parentInitial commit. (diff)
downloadkbuild-29cd838eab01ed7110f3ccb2e8c6a35c8a31dbcc.tar.xz
kbuild-29cd838eab01ed7110f3ccb2e8c6a35c8a31dbcc.zip
Adding upstream version 1:0.1.9998svn3589+dfsg.upstream/1%0.1.9998svn3589+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/lib/kStuff/include/k')
-rw-r--r--src/lib/kStuff/include/k/kAvlTmpl/kAvlBase.h626
-rw-r--r--src/lib/kStuff/include/k/kAvlTmpl/kAvlDestroy.h129
-rw-r--r--src/lib/kStuff/include/k/kAvlTmpl/kAvlDoWithAll.h166
-rw-r--r--src/lib/kStuff/include/k/kAvlTmpl/kAvlEnum.h187
-rw-r--r--src/lib/kStuff/include/k/kAvlTmpl/kAvlGet.h89
-rw-r--r--src/lib/kStuff/include/k/kAvlTmpl/kAvlGetBestFit.h112
-rw-r--r--src/lib/kStuff/include/k/kAvlTmpl/kAvlGetWithParent.h65
-rw-r--r--src/lib/kStuff/include/k/kAvlTmpl/kAvlRemove2.h133
-rw-r--r--src/lib/kStuff/include/k/kAvlTmpl/kAvlRemoveBestFit.h70
-rw-r--r--src/lib/kStuff/include/k/kAvlTmpl/kAvlUndef.h79
-rw-r--r--src/lib/kStuff/include/k/kAvlU32.h66
-rw-r--r--src/lib/kStuff/include/k/kAvloU32.h75
-rw-r--r--src/lib/kStuff/include/k/kAvlrU32.h71
-rw-r--r--src/lib/kStuff/include/k/kCpu.h68
-rw-r--r--src/lib/kStuff/include/k/kCpus.h157
-rw-r--r--src/lib/kStuff/include/k/kDbg.h243
-rw-r--r--src/lib/kStuff/include/k/kDbgAll.h168
-rw-r--r--src/lib/kStuff/include/k/kDbgBase.h248
-rw-r--r--src/lib/kStuff/include/k/kDefs.h596
-rw-r--r--src/lib/kStuff/include/k/kErr.h68
-rw-r--r--src/lib/kStuff/include/k/kErrors.h327
-rw-r--r--src/lib/kStuff/include/k/kHlp.h53
-rw-r--r--src/lib/kStuff/include/k/kHlpAlloc.h78
-rw-r--r--src/lib/kStuff/include/k/kHlpAssert.h369
-rw-r--r--src/lib/kStuff/include/k/kHlpDefs.h55
-rw-r--r--src/lib/kStuff/include/k/kHlpEnv.h55
-rw-r--r--src/lib/kStuff/include/k/kHlpPath.h57
-rw-r--r--src/lib/kStuff/include/k/kHlpProcess.h54
-rw-r--r--src/lib/kStuff/include/k/kHlpSem.h54
-rw-r--r--src/lib/kStuff/include/k/kHlpString.h156
-rw-r--r--src/lib/kStuff/include/k/kHlpSys.h79
-rw-r--r--src/lib/kStuff/include/k/kHlpThread.h55
-rw-r--r--src/lib/kStuff/include/k/kLdr.h959
-rw-r--r--src/lib/kStuff/include/k/kLdrFmts/lx.h485
-rw-r--r--src/lib/kStuff/include/k/kLdrFmts/mach-o.h997
-rw-r--r--src/lib/kStuff/include/k/kLdrFmts/mz.h70
-rw-r--r--src/lib/kStuff/include/k/kLdrFmts/pe.h566
-rw-r--r--src/lib/kStuff/include/k/kMagics.h43
-rw-r--r--src/lib/kStuff/include/k/kRbTmpl/kRbAssert.h136
-rw-r--r--src/lib/kStuff/include/k/kRbTmpl/kRbBase.h609
-rw-r--r--src/lib/kStuff/include/k/kRbTmpl/kRbDestroy.h129
-rw-r--r--src/lib/kStuff/include/k/kRbTmpl/kRbDoWithAll.h166
-rw-r--r--src/lib/kStuff/include/k/kRbTmpl/kRbEnum.h187
-rw-r--r--src/lib/kStuff/include/k/kRbTmpl/kRbGet.h89
-rw-r--r--src/lib/kStuff/include/k/kRbTmpl/kRbGetBestFit.h112
-rw-r--r--src/lib/kStuff/include/k/kRbTmpl/kRbGetWithParent.h65
-rw-r--r--src/lib/kStuff/include/k/kRbTmpl/kRbRemove2.h133
-rw-r--r--src/lib/kStuff/include/k/kRbTmpl/kRbRemoveBestFit.h70
-rw-r--r--src/lib/kStuff/include/k/kRbTmpl/kRbUndef.h79
-rw-r--r--src/lib/kStuff/include/k/kRbU32.h68
-rw-r--r--src/lib/kStuff/include/k/kRdr.h86
-rw-r--r--src/lib/kStuff/include/k/kRdrAll.h127
-rw-r--r--src/lib/kStuff/include/k/kTypes.h531
53 files changed, 10515 insertions, 0 deletions
diff --git a/src/lib/kStuff/include/k/kAvlTmpl/kAvlBase.h b/src/lib/kStuff/include/k/kAvlTmpl/kAvlBase.h
new file mode 100644
index 0000000..90efdee
--- /dev/null
+++ b/src/lib/kStuff/include/k/kAvlTmpl/kAvlBase.h
@@ -0,0 +1,626 @@
+/* $Id: kAvlBase.h 36 2009-11-09 22:49:02Z bird $ */
+/** @file
+ * kAvlTmpl - Templated AVL Trees, The Mandatory Base Code.
+ */
+
+/*
+ * Copyright (c) 2001-2009 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.
+ */
+
+/** @page pg_kAvlTmpl Template Configuration.
+ *
+ * This is a templated implementation of AVL trees in C. The template
+ * parameters relates to the kind of key used and how duplicates are
+ * treated.
+ *
+ * \#define KAVL_EQUAL_ALLOWED
+ * Define this to tell us that equal keys are allowed.
+ * Then Equal keys will be put in a list pointed to by KAVLNODE::pList.
+ * This is by default not defined.
+ *
+ * \#define KAVL_CHECK_FOR_EQUAL_INSERT
+ * Define this to enable insert check for equal nodes.
+ * This is by default not defined.
+ *
+ * \#define KAVL_MAX_STACK
+ * Use this to specify the max number of stack entries the stack will use when
+ * inserting and removing nodes from the tree. The size should be something like
+ * log2(<max nodes>) + 3
+ * Must be defined.
+ *
+ * \#define KAVL_RANGE
+ * Define this to enable key ranges.
+ *
+ * \#define KAVL_OFFSET
+ * Define this to link the tree together using self relative offset
+ * instead of memory pointers, thus making the entire tree relocatable
+ * provided all the nodes - including the root node variable - are moved
+ * the exact same distance.
+ *
+ * \#define KAVL_LOOKTHRU
+ * Define this to employ a lookthru cache (direct) to speed up lookup for
+ * some usage patterns. The value should be the number of members of the
+ * array.
+ *
+ * \#define KAVL_LOOKTHRU_HASH(Key)
+ * Define this to specify a more efficient translation of the key into
+ * a lookthru array index. The default is key % size.
+ * For some key types this is required as the default will not compile.
+ *
+ * \#define KAVL_LOCKED
+ * Define this if you wish for the tree to be locked via the
+ * KAVL_WRITE_LOCK, KAVL_WRITE_UNLOCK, KAVL_READ_LOCK and
+ * KAVL_READ_UNLOCK macros. If not defined the tree will not be subject
+ * do any kind of locking and the problem of concurrency is left the user.
+ *
+ * \#define KAVL_WRITE_LOCK(pRoot)
+ * Lock the tree for writing.
+ *
+ * \#define KAVL_WRITE_UNLOCK(pRoot)
+ * Counteracts KAVL_WRITE_LOCK.
+ *
+ * \#define KAVL_READ_LOCK(pRoot)
+ * Lock the tree for reading.
+ *
+ * \#define KAVL_READ_UNLOCK(pRoot)
+ * Counteracts KAVL_READ_LOCK.
+ *
+ * \#define KAVLKEY
+ * Define this to the name of the AVL key type.
+ *
+ * \#define KAVL_STD_KEY_COMP
+ * Define this to use the standard key compare macros. If not set all the
+ * compare operations for KAVLKEY have to be defined: KAVL_G, KAVL_E, KAVL_NE,
+ * KAVL_R_IS_IDENTICAL, KAVL_R_IS_INTERSECTING and KAVL_R_IS_IN_RANGE. The
+ * latter three are only required when KAVL_RANGE is defined.
+ *
+ * \#define KAVLNODE
+ * Define this to the name (typedef) of the AVL node structure. This
+ * structure must have a mpLeft, mpRight, mKey and mHeight member.
+ * If KAVL_RANGE is defined a mKeyLast is also required.
+ * If KAVL_EQUAL_ALLOWED is defined a mpList member is required.
+ * It's possible to use other member names by redefining the names.
+ *
+ * \#define KAVLTREEPTR
+ * Define this to the name (typedef) of the tree pointer type. This is
+ * required when KAVL_OFFSET is defined. When not defined it defaults
+ * to KAVLNODE *.
+ *
+ * \#define KAVLROOT
+ * Define this to the name (typedef) of the AVL root structure. This
+ * is optional. However, if specified it must at least have a mpRoot
+ * member of KAVLTREEPTR type. If KAVL_LOOKTHRU is non-zero a
+ * maLookthru[KAVL_LOOKTHRU] member of the KAVLTREEPTR type is also
+ * required.
+ *
+ * \#define KAVL_FN
+ * Use this to alter the names of the AVL functions.
+ * Must be defined.
+ *
+ * \#define KAVL_TYPE(prefix, name)
+ * Use this to make external type names and unique. The prefix may be empty.
+ * Must be defined.
+ *
+ * \#define KAVL_INT(name)
+ * Use this to make internal type names and unique. The prefix may be empty.
+ * Must be defined.
+ *
+ * \#define KAVL_DECL(rettype)
+ * Function declaration macro that should be set according to the scope
+ * the instantiated template should have. For instance an inlined scope
+ * (private or public) should K_DECL_INLINE(rettype) here.
+ *
+ * This version of the kAVL tree offers the option of inlining the entire
+ * implementation. This depends on the compiler doing a decent job in both
+ * making use of the inlined code and to eliminate const variables.
+ */
+
+
+/*******************************************************************************
+* Internal Functions *
+*******************************************************************************/
+#include <k/kDefs.h>
+#include <k/kTypes.h>
+#include <k/kHlpAssert.h>
+
+
+/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
+#define KAVL_HEIGHTOF(pNode) ((KU8)((pNode) != NULL ? (pNode)->mHeight : 0))
+
+/** @def KAVL_GET_POINTER
+ * Reads a 'pointer' value.
+ *
+ * @returns The native pointer.
+ * @param pp Pointer to the pointer to read.
+ * @internal
+ */
+
+/** @def KAVL_GET_POINTER_NULL
+ * Reads a 'pointer' value which can be KAVL_NULL.
+ *
+ * @returns The native pointer.
+ * @returns NULL pointer if KAVL_NULL.
+ * @param pp Pointer to the pointer to read.
+ * @internal
+ */
+
+/** @def KAVL_SET_POINTER
+ * Writes a 'pointer' value.
+ * For offset-based schemes offset relative to pp is calculated and assigned to *pp.
+ *
+ * @returns stored pointer.
+ * @param pp Pointer to where to store the pointer.
+ * @param p Native pointer to assign to *pp.
+ * @internal
+ */
+
+/** @def KAVL_SET_POINTER_NULL
+ * Writes a 'pointer' value which can be KAVL_NULL.
+ *
+ * For offset-based schemes offset relative to pp is calculated and assigned to *pp,
+ * if p is not KAVL_NULL of course.
+ *
+ * @returns stored pointer.
+ * @param pp Pointer to where to store the pointer.
+ * @param pp2 Pointer to where to pointer to assign to pp. This can be KAVL_NULL
+ * @internal
+ */
+
+#ifndef KAVLTREEPTR
+# define KAVLTREEPTR KAVLNODE *
+#endif
+
+#ifndef KAVLROOT
+# define KAVLROOT KAVL_TYPE(,ROOT)
+# define KAVL_NEED_KAVLROOT
+#endif
+
+#ifdef KAVL_LOOKTHRU
+# ifndef KAVL_LOOKTHRU_HASH
+# define KAVL_LOOKTHRU_HASH(Key) ( (Key) % (KAVL_LOOKTHRU) )
+# endif
+#elif defined(KAVL_LOOKTHRU_HASH)
+# error "KAVL_LOOKTHRU_HASH without KAVL_LOOKTHRU!"
+#endif
+
+#ifdef KAVL_LOOKTHRU
+# define KAVL_LOOKTHRU_INVALIDATE_NODE(pRoot, pNode, Key) \
+ do { \
+ KAVLTREEPTR **ppEntry = &pRoot->maLookthru[KAVL_LOOKTHRU_HASH(Key)]; \
+ if ((pNode) == KAVL_GET_POINTER_NULL(ppEntry)) \
+ *ppEntry = KAVL_NULL; \
+ } while (0)
+#else
+# define KAVL_LOOKTHRU_INVALIDATE_NODE(pRoot, pNode, Key) do { } while (0)
+#endif
+
+#ifndef KAVL_LOCKED
+# define KAVL_WRITE_LOCK(pRoot) do { } while (0)
+# define KAVL_WRITE_UNLOCK(pRoot) do { } while (0)
+# define KAVL_READ_LOCK(pRoot) do { } while (0)
+# define KAVL_READ_UNLOCK(pRoot) do { } while (0)
+#endif
+
+#ifdef KAVL_OFFSET
+# define KAVL_GET_POINTER(pp) ( (KAVLNODE *)((KIPTR)(pp) + *(pp)) )
+# define KAVL_GET_POINTER_NULL(pp) ( *(pp) != KAVL_NULL ? KAVL_GET_POINTER(pp) : NULL )
+# define KAVL_SET_POINTER(pp, p) ( (*(pp)) = ((KIPTR)(p) - (KIPTR)(pp)) )
+# define KAVL_SET_POINTER_NULL(pp, pp2) ( (*(pp)) = *(pp2) != KAVL_NULL ? (KIPTR)KAVL_GET_POINTER(pp2) - (KIPTR)(pp) : KAVL_NULL )
+#else
+# define KAVL_GET_POINTER(pp) ( *(pp) )
+# define KAVL_GET_POINTER_NULL(pp) ( *(pp) )
+# define KAVL_SET_POINTER(pp, p) ( (*(pp)) = (p) )
+# define KAVL_SET_POINTER_NULL(pp, pp2) ( (*(pp)) = *(pp2) )
+#endif
+
+
+/** @def KAVL_NULL
+ * The NULL 'pointer' equivalent.
+ */
+#ifdef KAVL_OFFSET
+# define KAVL_NULL 0
+#else
+# define KAVL_NULL NULL
+#endif
+
+#ifdef KAVL_STD_KEY_COMP
+# define KAVL_G(key1, key2) ( (key1) > (key2) )
+# define KAVL_E(key1, key2) ( (key1) == (key2) )
+# define KAVL_NE(key1, key2) ( (key1) != (key2) )
+# ifdef KAVL_RANGE
+# define KAVL_R_IS_IDENTICAL(key1B, key2B, key1E, key2E) ( (key1B) == (key2B) && (key1E) == (key2E) )
+# define KAVL_R_IS_INTERSECTING(key1B, key2B, key1E, key2E) ( (key1B) <= (key2E) && (key1E) >= (key2B) )
+# define KAVL_R_IS_IN_RANGE(key1B, key1E, key2) KAVL_R_IS_INTERSECTING(key1B, key2, key1E, key2)
+# endif
+#endif
+
+#ifndef KAVL_RANGE
+# define KAVL_R_IS_INTERSECTING(key1B, key2B, key1E, key2E) KAVL_E(key1B, key2B)
+# define KAVL_R_IS_IDENTICAL(key1B, key2B, key1E, key2E) KAVL_E(key1B, key2B)
+#endif
+
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * Stack used to avoid recursive calls during insert and removal.
+ */
+typedef struct
+{
+ unsigned cEntries;
+ KAVLTREEPTR *aEntries[KAVL_MAX_STACK];
+} KAVL_INT(STACK);
+
+/**
+ * The callback used by the Destroy and DoWithAll functions.
+ */
+typedef int (* KAVL_TYPE(PFN,CALLBACK))(KAVLNODE *, void *);
+
+#ifdef KAVL_NEED_KAVLROOT
+/**
+ * The AVL root structure.
+ */
+typedef struct
+{
+ KAVLTREEPTR mpRoot;
+# ifdef KAVL_LOOKTHRU
+ KAVLTREEPTR maLookthru[KAVL_LOOKTHRU];
+# endif
+} KAVLROOT;
+#endif
+
+
+/**
+ * Rewinds a stack of node pointer pointers, rebalancing the tree.
+ *
+ * @param pStack Pointer to stack to rewind.
+ * @sketch LOOP thru all stack entries
+ * BEGIN
+ * Get pointer to pointer to node (and pointer to node) from the stack.
+ * IF 2 higher left subtree than in right subtree THEN
+ * BEGIN
+ * IF higher (or equal) left-sub-subtree than right-sub-subtree THEN
+ * * n+2|n+3
+ * / \ / \
+ * n+2 n ==> n+1 n+1|n+2
+ * / \ / \
+ * n+1 n|n+1 n|n+1 n
+ *
+ * Or with keys:
+ *
+ * 4 2
+ * / \ / \
+ * 2 5 ==> 1 4
+ * / \ / \
+ * 1 3 3 5
+ *
+ * ELSE
+ * * n+2
+ * / \ / \
+ * n+2 n n+1 n+1
+ * / \ ==> / \ / \
+ * n n+1 n L R n
+ * / \
+ * L R
+ *
+ * Or with keys:
+ * 6 4
+ * / \ / \
+ * 2 7 ==> 2 6
+ * / \ / \ / \
+ * 1 4 1 3 5 7
+ * / \
+ * 3 5
+ * END
+ * ELSE IF 2 higher in right subtree than in left subtree THEN
+ * BEGIN
+ * Same as above but left <==> right. (invert the picture)
+ * ELSE
+ * IF correct height THEN break
+ * ELSE correct height.
+ * END
+ */
+K_DECL_INLINE(void) KAVL_FN(Rebalance)(KAVL_INT(STACK) *pStack)
+{
+ while (pStack->cEntries > 0)
+ {
+ KAVLTREEPTR *ppNode = pStack->aEntries[--pStack->cEntries];
+ KAVLNODE *pNode = KAVL_GET_POINTER(ppNode);
+ KAVLNODE *pLeftNode = KAVL_GET_POINTER_NULL(&pNode->mpLeft);
+ KU8 uLeftHeight = KAVL_HEIGHTOF(pLeftNode);
+ KAVLNODE *pRightNode = KAVL_GET_POINTER_NULL(&pNode->mpRight);
+ KU8 uRightHeight = KAVL_HEIGHTOF(pRightNode);
+
+ if (uRightHeight + 1 < uLeftHeight)
+ {
+ KAVLNODE *pLeftLeftNode = KAVL_GET_POINTER_NULL(&pLeftNode->mpLeft);
+ KAVLNODE *pLeftRightNode = KAVL_GET_POINTER_NULL(&pLeftNode->mpRight);
+ KU8 uLeftRightHeight = KAVL_HEIGHTOF(pLeftRightNode);
+
+ if (KAVL_HEIGHTOF(pLeftLeftNode) >= uLeftRightHeight)
+ {
+ KAVL_SET_POINTER_NULL(&pNode->mpLeft, &pLeftNode->mpRight);
+ KAVL_SET_POINTER(&pLeftNode->mpRight, pNode);
+ pLeftNode->mHeight = (KU8)(1 + (pNode->mHeight = (KU8)(1 + uLeftRightHeight)));
+ KAVL_SET_POINTER(ppNode, pLeftNode);
+ }
+ else
+ {
+ KAVL_SET_POINTER_NULL(&pLeftNode->mpRight, &pLeftRightNode->mpLeft);
+ KAVL_SET_POINTER_NULL(&pNode->mpLeft, &pLeftRightNode->mpRight);
+ KAVL_SET_POINTER(&pLeftRightNode->mpLeft, pLeftNode);
+ KAVL_SET_POINTER(&pLeftRightNode->mpRight, pNode);
+ pLeftNode->mHeight = pNode->mHeight = uLeftRightHeight;
+ pLeftRightNode->mHeight = uLeftHeight;
+ KAVL_SET_POINTER(ppNode, pLeftRightNode);
+ }
+ }
+ else if (uLeftHeight + 1 < uRightHeight)
+ {
+ KAVLNODE *pRightLeftNode = KAVL_GET_POINTER_NULL(&pRightNode->mpLeft);
+ KU8 uRightLeftHeight = KAVL_HEIGHTOF(pRightLeftNode);
+ KAVLNODE *pRightRightNode = KAVL_GET_POINTER_NULL(&pRightNode->mpRight);
+
+ if (KAVL_HEIGHTOF(pRightRightNode) >= uRightLeftHeight)
+ {
+ KAVL_SET_POINTER_NULL(&pNode->mpRight, &pRightNode->mpLeft);
+ KAVL_SET_POINTER(&pRightNode->mpLeft, pNode);
+ pRightNode->mHeight = (KU8)(1 + (pNode->mHeight = (KU8)(1 + uRightLeftHeight)));
+ KAVL_SET_POINTER(ppNode, pRightNode);
+ }
+ else
+ {
+ KAVL_SET_POINTER_NULL(&pRightNode->mpLeft, &pRightLeftNode->mpRight);
+ KAVL_SET_POINTER_NULL(&pNode->mpRight, &pRightLeftNode->mpLeft);
+ KAVL_SET_POINTER(&pRightLeftNode->mpRight, pRightNode);
+ KAVL_SET_POINTER(&pRightLeftNode->mpLeft, pNode);
+ pRightNode->mHeight = pNode->mHeight = uRightLeftHeight;
+ pRightLeftNode->mHeight = uRightHeight;
+ KAVL_SET_POINTER(ppNode, pRightLeftNode);
+ }
+ }
+ else
+ {
+ KU8 uHeight = (KU8)(K_MAX(uLeftHeight, uRightHeight) + 1);
+ if (uHeight == pNode->mHeight)
+ break;
+ pNode->mHeight = uHeight;
+ }
+ }
+
+}
+
+
+/**
+ * Initializes the root of the AVL-tree.
+ *
+ * @param pTree Pointer to the root structure.
+ */
+KAVL_DECL(void) KAVL_FN(Init)(KAVLROOT *pRoot)
+{
+#ifdef KAVL_LOOKTHRU
+ unsigned i;
+#endif
+
+ pRoot->mpRoot = KAVL_NULL;
+#ifdef KAVL_LOOKTHRU
+ for (i = 0; i < (KAVL_LOOKTHRU); i++)
+ pRoot->maLookthru[i] = KAVL_NULL;
+#endif
+}
+
+
+/**
+ * Inserts a node into the AVL-tree.
+ * @returns K_TRUE if inserted.
+ * K_FALSE if node exists in tree.
+ * @param pRoot Pointer to the AVL-tree root structure.
+ * @param pNode Pointer to the node which is to be added.
+ * @sketch Find the location of the node (using binary tree algorithm.):
+ * LOOP until NULL leaf pointer
+ * BEGIN
+ * Add node pointer pointer to the AVL-stack.
+ * IF new-node-key < node key THEN
+ * left
+ * ELSE
+ * right
+ * END
+ * Fill in leaf node and insert it.
+ * Rebalance the tree.
+ */
+KAVL_DECL(KBOOL) KAVL_FN(Insert)(KAVLROOT *pRoot, KAVLNODE *pNode)
+{
+ KAVL_INT(STACK) AVLStack;
+ KAVLTREEPTR *ppCurNode = &pRoot->mpRoot;
+ register KAVLKEY Key = pNode->mKey;
+#ifdef KAVL_RANGE
+ register KAVLKEY KeyLast = pNode->mKeyLast;
+#endif
+
+#ifdef KAVL_RANGE
+ if (Key > KeyLast)
+ return K_FALSE;
+#endif
+
+ KAVL_WRITE_LOCK(pRoot);
+
+ AVLStack.cEntries = 0;
+ while (*ppCurNode != KAVL_NULL)
+ {
+ register KAVLNODE *pCurNode = KAVL_GET_POINTER(ppCurNode);
+
+ kHlpAssert(AVLStack.cEntries < KAVL_MAX_STACK);
+ AVLStack.aEntries[AVLStack.cEntries++] = ppCurNode;
+#ifdef KAVL_EQUAL_ALLOWED
+ if (KAVL_R_IS_IDENTICAL(pCurNode->mKey, Key, pCurNode->mKeyLast, KeyLast))
+ {
+ /*
+ * If equal then we'll use a list of equal nodes.
+ */
+ pNode->mpLeft = pNode->mpRight = KAVL_NULL;
+ pNode->mHeight = 0;
+ KAVL_SET_POINTER_NULL(&pNode->mpList, &pCurNode->mpList);
+ KAVL_SET_POINTER(&pCurNode->mpList, pNode);
+ KAVL_WRITE_UNLOCK(pRoot);
+ return K_TRUE;
+ }
+#endif
+#ifdef KAVL_CHECK_FOR_EQUAL_INSERT
+ if (KAVL_R_IS_INTERSECTING(pCurNode->mKey, Key, pCurNode->mKeyLast, KeyLast))
+ {
+ KAVL_WRITE_UNLOCK(pRoot);
+ return K_FALSE;
+ }
+#endif
+ if (KAVL_G(pCurNode->mKey, Key))
+ ppCurNode = &pCurNode->mpLeft;
+ else
+ ppCurNode = &pCurNode->mpRight;
+ }
+
+ pNode->mpLeft = pNode->mpRight = KAVL_NULL;
+#ifdef KAVL_EQUAL_ALLOWED
+ pNode->mpList = KAVL_NULL;
+#endif
+ pNode->mHeight = 1;
+ KAVL_SET_POINTER(ppCurNode, pNode);
+
+ KAVL_FN(Rebalance)(&AVLStack);
+
+ KAVL_WRITE_UNLOCK(pRoot);
+ return K_TRUE;
+}
+
+
+/**
+ * Removes a node from the AVL-tree.
+ * @returns Pointer to the node.
+ * @param pRoot Pointer to the AVL-tree root structure.
+ * @param Key Key value of the node which is to be removed.
+ * @sketch Find the node which is to be removed:
+ * LOOP until not found
+ * BEGIN
+ * Add node pointer pointer to the AVL-stack.
+ * IF the keys matches THEN break!
+ * IF remove key < node key THEN
+ * left
+ * ELSE
+ * right
+ * END
+ * IF found THEN
+ * BEGIN
+ * IF left node not empty THEN
+ * BEGIN
+ * Find the right most node in the left tree while adding the pointer to the pointer to it's parent to the stack:
+ * Start at left node.
+ * LOOP until right node is empty
+ * BEGIN
+ * Add to stack.
+ * go right.
+ * END
+ * Link out the found node.
+ * Replace the node which is to be removed with the found node.
+ * Correct the stack entry for the pointer to the left tree.
+ * END
+ * ELSE
+ * BEGIN
+ * Move up right node.
+ * Remove last stack entry.
+ * END
+ * Balance tree using stack.
+ * END
+ * return pointer to the removed node (if found).
+ */
+KAVL_DECL(KAVLNODE *) KAVL_FN(Remove)(KAVLROOT *pRoot, KAVLKEY Key)
+{
+ KAVL_INT(STACK) AVLStack;
+ KAVLTREEPTR *ppDeleteNode = &pRoot->mpRoot;
+ register KAVLNODE *pDeleteNode;
+
+ KAVL_WRITE_LOCK(pRoot);
+
+ AVLStack.cEntries = 0;
+ for (;;)
+ {
+ if (*ppDeleteNode == KAVL_NULL)
+ {
+ KAVL_WRITE_UNLOCK(pRoot);
+ return NULL;
+ }
+ pDeleteNode = KAVL_GET_POINTER(ppDeleteNode);
+
+ kHlpAssert(AVLStack.cEntries < KAVL_MAX_STACK);
+ AVLStack.aEntries[AVLStack.cEntries++] = ppDeleteNode;
+ if (KAVL_E(pDeleteNode->mKey, Key))
+ break;
+
+ if (KAVL_G(pDeleteNode->mKey, Key))
+ ppDeleteNode = &pDeleteNode->mpLeft;
+ else
+ ppDeleteNode = &pDeleteNode->mpRight;
+ }
+
+ if (pDeleteNode->mpLeft != KAVL_NULL)
+ {
+ /* find the rightmost node in the left tree. */
+ const unsigned iStackEntry = AVLStack.cEntries;
+ KAVLTREEPTR *ppLeftLeast = &pDeleteNode->mpLeft;
+ register KAVLNODE *pLeftLeast = KAVL_GET_POINTER(ppLeftLeast);
+
+ while (pLeftLeast->mpRight != KAVL_NULL)
+ {
+ kHlpAssert(AVLStack.cEntries < KAVL_MAX_STACK);
+ AVLStack.aEntries[AVLStack.cEntries++] = ppLeftLeast;
+ ppLeftLeast = &pLeftLeast->mpRight;
+ pLeftLeast = KAVL_GET_POINTER(ppLeftLeast);
+ }
+
+ /* link out pLeftLeast */
+ KAVL_SET_POINTER_NULL(ppLeftLeast, &pLeftLeast->mpLeft);
+
+ /* link it in place of the delete node. */
+ KAVL_SET_POINTER_NULL(&pLeftLeast->mpLeft, &pDeleteNode->mpLeft);
+ KAVL_SET_POINTER_NULL(&pLeftLeast->mpRight, &pDeleteNode->mpRight);
+ pLeftLeast->mHeight = pDeleteNode->mHeight;
+ KAVL_SET_POINTER(ppDeleteNode, pLeftLeast);
+ AVLStack.aEntries[iStackEntry] = &pLeftLeast->mpLeft;
+ }
+ else
+ {
+ KAVL_SET_POINTER_NULL(ppDeleteNode, &pDeleteNode->mpRight);
+ AVLStack.cEntries--;
+ }
+
+ KAVL_FN(Rebalance)(&AVLStack);
+
+ KAVL_LOOKTHRU_INVALIDATE_NODE(pRoot, pDeleteNode, Key);
+
+ KAVL_WRITE_UNLOCK(pRoot);
+ return pDeleteNode;
+}
+
diff --git a/src/lib/kStuff/include/k/kAvlTmpl/kAvlDestroy.h b/src/lib/kStuff/include/k/kAvlTmpl/kAvlDestroy.h
new file mode 100644
index 0000000..17115f3
--- /dev/null
+++ b/src/lib/kStuff/include/k/kAvlTmpl/kAvlDestroy.h
@@ -0,0 +1,129 @@
+/* $Id: kAvlDestroy.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kAvlTmpl - Templated AVL Trees, Destroy the tree.
+ */
+
+/*
+ * Copyright (c) 1999-2009 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.
+ */
+
+/**
+ * Destroys the specified tree, starting with the root node and working our way down.
+ *
+ * @returns 0 on success.
+ * @returns Return value from callback on failure. On failure, the tree will be in
+ * an unbalanced condition and only further calls to the Destroy should be
+ * made on it. Note that the node we fail on will be considered dead and
+ * no action is taken to link it back into the tree.
+ * @param pRoot Pointer to the AVL-tree root structure.
+ * @param pfnCallBack Pointer to callback function.
+ * @param pvUser User parameter passed on to the callback function.
+ */
+KAVL_DECL(int) KAVL_FN(Destroy)(KAVLROOT *pRoot, KAVL_TYPE(PFN,CALLBACK) pfnCallBack, void *pvUser)
+{
+#ifdef KAVL_LOOKTHRU
+ unsigned i;
+#endif
+ unsigned cEntries;
+ KAVLNODE *apEntries[KAVL_MAX_STACK];
+ int rc;
+
+ KAVL_WRITE_LOCK(pRoot);
+ if (pRoot->mpRoot == KAVL_NULL)
+ {
+ KAVL_WRITE_UNLOCK(pRoot);
+ return 0;
+ }
+
+#ifdef KAVL_LOOKTHRU
+ /*
+ * Kill the lookthru cache.
+ */
+ for (i = 0; i < (KAVL_LOOKTHRU); i++)
+ pRoot->maLookthru[i] = KAVL_NULL;
+#endif
+
+ cEntries = 1;
+ apEntries[0] = KAVL_GET_POINTER(&pRoot->mpRoot);
+ while (cEntries > 0)
+ {
+ /*
+ * Process the subtrees first.
+ */
+ KAVLNODE *pNode = apEntries[cEntries - 1];
+ if (pNode->mpLeft != KAVL_NULL)
+ apEntries[cEntries++] = KAVL_GET_POINTER(&pNode->mpLeft);
+ else if (pNode->mpRight != KAVL_NULL)
+ apEntries[cEntries++] = KAVL_GET_POINTER(&pNode->mpRight);
+ else
+ {
+#ifdef KAVL_EQUAL_ALLOWED
+ /*
+ * Process nodes with the same key.
+ */
+ while (pNode->pList != KAVL_NULL)
+ {
+ KAVLNODE *pEqual = KAVL_GET_POINTER(&pNode->pList);
+ KAVL_SET_POINTER(&pNode->pList, KAVL_GET_POINTER_NULL(&pEqual->pList));
+ pEqual->pList = KAVL_NULL;
+
+ rc = pfnCallBack(pEqual, pvUser);
+ if (rc)
+ {
+ KAVL_WRITE_UNLOCK(pRoot);
+ return rc;
+ }
+ }
+#endif
+
+ /*
+ * Unlink the node.
+ */
+ if (--cEntries > 0)
+ {
+ KAVLNODE *pParent = apEntries[cEntries - 1];
+ if (KAVL_GET_POINTER(&pParent->mpLeft) == pNode)
+ pParent->mpLeft = KAVL_NULL;
+ else
+ pParent->mpRight = KAVL_NULL;
+ }
+ else
+ pRoot->mpRoot = KAVL_NULL;
+
+ kHlpAssert(pNode->mpLeft == KAVL_NULL);
+ kHlpAssert(pNode->mpRight == KAVL_NULL);
+ rc = pfnCallBack(pNode, pvUser);
+ if (rc)
+ {
+ KAVL_WRITE_UNLOCK(pRoot);
+ return rc;
+ }
+ }
+ } /* while */
+ kHlpAssert(pRoot->mpRoot == KAVL_NULL);
+
+ KAVL_WRITE_UNLOCK(pRoot);
+ return 0;
+}
+
diff --git a/src/lib/kStuff/include/k/kAvlTmpl/kAvlDoWithAll.h b/src/lib/kStuff/include/k/kAvlTmpl/kAvlDoWithAll.h
new file mode 100644
index 0000000..f2eaba1
--- /dev/null
+++ b/src/lib/kStuff/include/k/kAvlTmpl/kAvlDoWithAll.h
@@ -0,0 +1,166 @@
+/* $Id: kAvlDoWithAll.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kAvlTmpl - Templated AVL Trees, The Callback Iterator.
+ */
+
+/*
+ * Copyright (c) 1999-2009 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.
+ */
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * Stack used by DoWithAll to avoid recusive function calls.
+ */
+typedef struct
+{
+ unsigned cEntries;
+ KAVLNODE *aEntries[KAVL_MAX_STACK];
+ char achFlags[KAVL_MAX_STACK];
+ KAVLROOT pRoot;
+} KAVL_INT(STACK2);
+
+
+/**
+ * Iterates thru all nodes in the given tree.
+ *
+ * @returns 0 on success. Return from callback on failure.
+ * @param pRoot Pointer to the AVL-tree root structure.
+ * @param fFromLeft K_TRUE: Left to right.
+ * K_FALSE: Right to left.
+ * @param pfnCallBack Pointer to callback function.
+ * @param pvUser User parameter passed on to the callback function.
+ */
+KAVL_DECL(int) KAVL_FN(DoWithAll)(KAVLROOT *pRoot, KBOOL fFromLeft, KAVL_TYPE(PFN,CALLBACK) pfnCallBack, void *pvUser)
+{
+ KAVL_INT(STACK2) AVLStack;
+ KAVLNODE *pNode;
+#ifdef KAVL_EQUAL_ALLOWED
+ KAVLNODE *pEqual;
+#endif
+ int rc;
+
+ KAVL_READ_LOCK(pRoot);
+ if (pRoot->mpRoot == KAVL_NULL)
+ {
+ KAVL_READ_UNLOCK(pRoot);
+ return 0;
+ }
+
+ AVLStack.cEntries = 1;
+ AVLStack.achFlags[0] = 0;
+ AVLStack.aEntries[0] = KAVL_GET_POINTER(&pRoot->mpRoot);
+
+ if (fFromLeft)
+ { /* from left */
+ while (AVLStack.cEntries > 0)
+ {
+ pNode = AVLStack.aEntries[AVLStack.cEntries - 1];
+
+ /* left */
+ if (!AVLStack.achFlags[AVLStack.cEntries - 1]++)
+ {
+ if (pNode->mpLeft != KAVL_NULL)
+ {
+ AVLStack.achFlags[AVLStack.cEntries] = 0; /* 0 first, 1 last */
+ AVLStack.aEntries[AVLStack.cEntries++] = KAVL_GET_POINTER(&pNode->mpLeft);
+ continue;
+ }
+ }
+
+ /* center */
+ rc = pfnCallBack(pNode, pvUser);
+ if (rc)
+ return rc;
+#ifdef KAVL_EQUAL_ALLOWED
+ if (pNode->mpList != KAVL_NULL)
+ for (pEqual = KAVL_GET_POINTER(&pNode->mpList); pEqual; pEqual = KAVL_GET_POINTER_NULL(&pEqual->mpList))
+ {
+ rc = pfnCallBack(pEqual, pvUser);
+ if (rc)
+ {
+ KAVL_READ_UNLOCK(pRoot);
+ return rc;
+ }
+ }
+#endif
+
+ /* right */
+ AVLStack.cEntries--;
+ if (pNode->mpRight != KAVL_NULL)
+ {
+ AVLStack.achFlags[AVLStack.cEntries] = 0;
+ AVLStack.aEntries[AVLStack.cEntries++] = KAVL_GET_POINTER(&pNode->mpRight);
+ }
+ } /* while */
+ }
+ else
+ { /* from right */
+ while (AVLStack.cEntries > 0)
+ {
+ pNode = AVLStack.aEntries[AVLStack.cEntries - 1];
+
+ /* right */
+ if (!AVLStack.achFlags[AVLStack.cEntries - 1]++)
+ {
+ if (pNode->mpRight != KAVL_NULL)
+ {
+ AVLStack.achFlags[AVLStack.cEntries] = 0; /* 0 first, 1 last */
+ AVLStack.aEntries[AVLStack.cEntries++] = KAVL_GET_POINTER(&pNode->mpRight);
+ continue;
+ }
+ }
+
+ /* center */
+ rc = pfnCallBack(pNode, pvUser);
+ if (rc)
+ return rc;
+#ifdef KAVL_EQUAL_ALLOWED
+ if (pNode->mpList != KAVL_NULL)
+ for (pEqual = KAVL_GET_POINTER(&pNode->mpList); pEqual; pEqual = KAVL_GET_POINTER_NULL(&pEqual->pList))
+ {
+ rc = pfnCallBack(pEqual, pvUser);
+ if (rc)
+ {
+ KAVL_READ_UNLOCK(pRoot);
+ return rc;
+ }
+ }
+#endif
+
+ /* left */
+ AVLStack.cEntries--;
+ if (pNode->mpLeft != KAVL_NULL)
+ {
+ AVLStack.achFlags[AVLStack.cEntries] = 0;
+ AVLStack.aEntries[AVLStack.cEntries++] = KAVL_GET_POINTER(&pNode->mpLeft);
+ }
+ } /* while */
+ }
+
+ KAVL_READ_UNLOCK(pRoot);
+ return 0;
+}
+
diff --git a/src/lib/kStuff/include/k/kAvlTmpl/kAvlEnum.h b/src/lib/kStuff/include/k/kAvlTmpl/kAvlEnum.h
new file mode 100644
index 0000000..da151d1
--- /dev/null
+++ b/src/lib/kStuff/include/k/kAvlTmpl/kAvlEnum.h
@@ -0,0 +1,187 @@
+/* $Id: kAvlEnum.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kAvlTmpl - Templated AVL Trees, Node Enumeration.
+ */
+
+/*
+ * Copyright (c) 1999-2009 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.
+ */
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * Enumeration control data.
+ *
+ * This is initialized by BeginEnum and used by GetNext to figure out what
+ * to do next.
+ */
+typedef struct KAVL_TYPE(,ENUMDATA)
+{
+ KBOOL fFromLeft;
+ KI8 cEntries;
+ KU8 achFlags[KAVL_MAX_STACK];
+ KAVLNODE * aEntries[KAVL_MAX_STACK];
+} KAVL_TYPE(,ENUMDATA), *KAVL_TYPE(P,ENUMDATA);
+
+
+/**
+ * Ends an enumeration.
+ *
+ * The purpose of this function is to unlock the tree should the
+ * AVL implementation include locking. It's good practice to call
+ * it anyway even if the tree doesn't do any locking.
+ *
+ * @param pEnumData Pointer to enumeration control data.
+ */
+KAVL_DECL(void) KAVL_FN(EndEnum)(KAVL_TYPE(,ENUMDATA) *pEnumData)
+{
+ KAVLROOT pRoot = pEnumData->pRoot;
+ pEnumData->pRoot = NULL;
+ if (pRoot)
+ KAVL_READ_UNLOCK(pEnumData->pRoot);
+}
+
+
+/**
+ * Get the next node in the tree enumeration.
+ *
+ * The current implementation of this function willl not walk the mpList
+ * chain like the DoWithAll function does. This may be changed later.
+ *
+ * @returns Pointer to the next node in the tree.
+ * NULL is returned when the end of the tree has been reached,
+ * it is not necessary to call EndEnum in this case.
+ * @param pEnumData Pointer to enumeration control data.
+ */
+KAVL_DECL(KAVLNODE *) KAVL_FN(GetNext)(KAVL_TYPE(,ENUMDATA) *pEnumData)
+{
+ if (pEnumData->fFromLeft)
+ { /* from left */
+ while (pEnumData->cEntries > 0)
+ {
+ KAVLNODE *pNode = pEnumData->aEntries[pEnumData->cEntries - 1];
+
+ /* left */
+ if (pEnumData->achFlags[pEnumData->cEntries - 1] == 0)
+ {
+ pEnumData->achFlags[pEnumData->cEntries - 1]++;
+ if (pNode->mpLeft != KAVL_NULL)
+ {
+ pEnumData->achFlags[pEnumData->cEntries] = 0; /* 0 left, 1 center, 2 right */
+ pEnumData->aEntries[pEnumData->cEntries++] = KAVL_GET_POINTER(&pNode->mpLeft);
+ continue;
+ }
+ }
+
+ /* center */
+ if (pEnumData->achFlags[pEnumData->cEntries - 1] == 1)
+ {
+ pEnumData->achFlags[pEnumData->cEntries - 1]++;
+ return pNode;
+ }
+
+ /* right */
+ pEnumData->cEntries--;
+ if (pNode->mpRight != KAVL_NULL)
+ {
+ pEnumData->achFlags[pEnumData->cEntries] = 0;
+ pEnumData->aEntries[pEnumData->cEntries++] = KAVL_GET_POINTER(&pNode->mpRight);
+ }
+ } /* while */
+ }
+ else
+ { /* from right */
+ while (pEnumData->cEntries > 0)
+ {
+ KAVLNODE *pNode = pEnumData->aEntries[pEnumData->cEntries - 1];
+
+ /* right */
+ if (pEnumData->achFlags[pEnumData->cEntries - 1] == 0)
+ {
+ pEnumData->achFlags[pEnumData->cEntries - 1]++;
+ if (pNode->mpRight != KAVL_NULL)
+ {
+ pEnumData->achFlags[pEnumData->cEntries] = 0; /* 0 right, 1 center, 2 left */
+ pEnumData->aEntries[pEnumData->cEntries++] = KAVL_GET_POINTER(&pNode->mpRight);
+ continue;
+ }
+ }
+
+ /* center */
+ if (pEnumData->achFlags[pEnumData->cEntries - 1] == 1)
+ {
+ pEnumData->achFlags[pEnumData->cEntries - 1]++;
+ return pNode;
+ }
+
+ /* left */
+ pEnumData->cEntries--;
+ if (pNode->mpLeft != KAVL_NULL)
+ {
+ pEnumData->achFlags[pEnumData->cEntries] = 0;
+ pEnumData->aEntries[pEnumData->cEntries++] = KAVL_GET_POINTER(&pNode->mpLeft);
+ }
+ } /* while */
+ }
+
+ /*
+ * Call EndEnum.
+ */
+ KAVL_FN(EndEnum)(pEnumData);
+ return NULL;
+}
+
+
+/**
+ * Starts an enumeration of all nodes in the given AVL tree.
+ *
+ * The current implementation of this function will not walk the mpList
+ * chain like the DoWithAll function does. This may be changed later.
+ *
+ * @returns Pointer to the first node in the enumeration.
+ * If NULL is returned the tree is empty calling EndEnum isn't
+ * strictly necessary (although it will do no harm).
+ * @param pRoot Pointer to the AVL-tree root structure.
+ * @param pEnumData Pointer to enumeration control data.
+ * @param fFromLeft K_TRUE: Left to right.
+ * K_FALSE: Right to left.
+ */
+KAVL_DECL(KAVLNODE *) KAVL_FN(BeginEnum)(KAVLROOT *pRoot, KAVL_TYPE(,ENUMDATA) *pEnumData, KBOOL fFromLeft)
+{
+ KAVL_READ_LOCK(pRoot);
+ pEnumData->pRoot = pRoot;
+ if (pRoot->mpRoot != KAVL_NULL)
+ {
+ pEnumData->fFromLeft = fFromLeft;
+ pEnumData->cEntries = 1;
+ pEnumData->aEntries[0] = KAVL_GET_POINTER(pRoot->mpRoot);
+ pEnumData->achFlags[0] = 0;
+ }
+ else
+ pEnumData->cEntries = 0;
+
+ return KAVL_FN(GetNext)(pEnumData);
+}
+
diff --git a/src/lib/kStuff/include/k/kAvlTmpl/kAvlGet.h b/src/lib/kStuff/include/k/kAvlTmpl/kAvlGet.h
new file mode 100644
index 0000000..a80eb49
--- /dev/null
+++ b/src/lib/kStuff/include/k/kAvlTmpl/kAvlGet.h
@@ -0,0 +1,89 @@
+/* $Id: kAvlGet.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kAvlTmpl - Templated AVL Trees, Get a Node.
+ */
+
+/*
+ * Copyright (c) 1999-2009 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.
+ */
+
+/**
+ * Gets a node from the tree (does not remove it!)
+ *
+ * @returns Pointer to the node holding the given key.
+ * @param pRoot Pointer to the AVL-tree root structure.
+ * @param Key Key value of the node which is to be found.
+ */
+KAVL_DECL(KAVLNODE *) KAVL_FN(Get)(KAVLROOT *pRoot, KAVLKEY Key)
+{
+ KAVLNODE *pNode;
+#ifdef KAVL_LOOKTHRU_CACHE
+ KAVLTREEPTR *ppEntry;
+#endif
+
+ KAVL_READ_LOCK(pRoot);
+ if (pRoot->mpRoot == KAVL_NULL)
+ {
+ KAVL_READ_UNLOCK(pRoot);
+ return NULL;
+ }
+
+#ifdef KAVL_LOOKTHRU_CACHE
+ ppEntry = &pRoot->maLookthru[KAVL_LOOKTHRU_HASH(Key)];
+ pNode = KAVL_GET_POINTER_NULL(ppEntry);
+ if (!pNode || KAVL_NE(pNode->mKey, Key))
+#endif
+ {
+ pNode = KAVL_GET_POINTER(&pRoot->mpRoot);
+ while (KAVL_NE(pNode->mKey, Key))
+ {
+ if (KAVL_G(pNode->mKey, Key))
+ {
+ if (pNode->mpLeft == KAVL_NULL)
+ {
+ KAVL_READ_UNLOCK(pRoot);
+ return NULL;
+ }
+ pNode = KAVL_GET_POINTER(&pNode->mpLeft);
+ }
+ else
+ {
+ if (pNode->mpRight == KAVL_NULL)
+ {
+ KAVL_READ_UNLOCK(pRoot);
+ return NULL;
+ }
+ pNode = KAVL_GET_POINTER(&pNode->mpRight);
+ }
+ }
+
+#ifdef KAVL_LOOKTHRU_CACHE
+ KAVL_SET_POINTER(ppEntry, pNode);
+#endif
+ }
+
+ KAVL_READ_UNLOCK(pRoot);
+ return pNode;
+}
+
diff --git a/src/lib/kStuff/include/k/kAvlTmpl/kAvlGetBestFit.h b/src/lib/kStuff/include/k/kAvlTmpl/kAvlGetBestFit.h
new file mode 100644
index 0000000..1d51709
--- /dev/null
+++ b/src/lib/kStuff/include/k/kAvlTmpl/kAvlGetBestFit.h
@@ -0,0 +1,112 @@
+/* $Id: kAvlGetBestFit.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kAvlTmpl - Templated AVL Trees, Get Best Fitting Node.
+ */
+
+/*
+ * Copyright (c) 1999-2009 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.
+ */
+
+/**
+ * Finds the best fitting node in the tree for the given Key value.
+ *
+ * @returns Pointer to the best fitting node found.
+ * @param pRoot Pointer to the AVL-tree root structure.
+ * @param Key The Key of which is to be found a best fitting match for..
+ * @param fAbove K_TRUE: Returned node is have the closest key to Key from above.
+ * K_FALSE: Returned node is have the closest key to Key from below.
+ * @sketch The best fitting node is always located in the searchpath above you.
+ * >= (above): The node where you last turned left.
+ * <= (below): the node where you last turned right.
+ */
+KAVL_DECL(KAVLNODE *) KAVL_FN(GetBestFit)(KAVLROOT *pRoot, KAVLKEY Key, KBOOL fAbove)
+{
+ register KAVLNODE *pNode;
+ KAVLNODE *pNodeLast;
+
+ KAVL_READ_LOCK(pLook);
+ if (pRoot->mpRoot == KAVL_NULL)
+ {
+ KAVL_READ_UNLOCK(pLook);
+ return NULL;
+ }
+
+ pNode = KAVL_GET_POINTER(&pRoot->mpRoot);
+ pNodeLast = NULL;
+ if (fAbove)
+ { /* pNode->mKey >= Key */
+ while (KAVL_NE(pNode->mKey, Key))
+ {
+ if (KAVL_G(pNode->mKey, Key))
+ {
+ if (pNode->mpLeft == KAVL_NULL)
+ {
+ KAVL_READ_UNLOCK(pLook);
+ return pNode;
+ }
+ pNodeLast = pNode;
+ pNode = KAVL_GET_POINTER(&pNode->mpLeft);
+ }
+ else
+ {
+ if (pNode->mpRight == KAVL_NULL)
+ {
+ KAVL_READ_UNLOCK(pLook);
+ return pNodeLast;
+ }
+ pNode = KAVL_GET_POINTER(&pNode->mpRight);
+ }
+ }
+ }
+ else
+ { /* pNode->mKey <= Key */
+ while (KAVL_NE(pNode->mKey, Key))
+ {
+ if (KAVL_G(pNode->mKey, Key))
+ {
+ if (pNode->mpLeft == KAVL_NULL)
+ {
+ KAVL_READ_UNLOCK(pLook);
+ return pNodeLast;
+ }
+ pNode = KAVL_GET_POINTER(&pNode->mpLeft);
+ }
+ else
+ {
+ if (pNode->mpRight == KAVL_NULL)
+ {
+ KAVL_READ_UNLOCK(pLook);
+ return pNode;
+ }
+ pNodeLast = pNode;
+ pNode = KAVL_GET_POINTER(&pNode->mpRight);
+ }
+ }
+ }
+
+ /* perfect match or nothing. */
+ KAVL_READ_UNLOCK(pLook);
+ return pNode;
+}
+
diff --git a/src/lib/kStuff/include/k/kAvlTmpl/kAvlGetWithParent.h b/src/lib/kStuff/include/k/kAvlTmpl/kAvlGetWithParent.h
new file mode 100644
index 0000000..997c394
--- /dev/null
+++ b/src/lib/kStuff/include/k/kAvlTmpl/kAvlGetWithParent.h
@@ -0,0 +1,65 @@
+/* $Id: kAvlGetWithParent.h 34 2009-11-08 19:38:40Z bird $ */
+/** @file
+ * kAvlTmpl - Templated AVL Trees, Get Node With Parent.
+ */
+
+/*
+ * Copyright (c) 1999-2009 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.
+ */
+
+/**
+ * Gets a node from the tree and its parent node (if any).
+ * The tree remains unchanged.
+ *
+ * @returns Pointer to the node holding the given key.
+ * @param pRoot Pointer to the AVL-tree root structure.
+ * @param ppParent Pointer to a variable which will hold the pointer to the partent node on
+ * return. When no node is found, this will hold the last searched node.
+ * @param Key Key value of the node which is to be found.
+ */
+KAVL_DECL(KAVLNODE *) KAVL_FN(GetWithParent)(KAVLROOT *pRoot, KAVLNODE **ppParent, KAVLKEY Key)
+{
+ register KAVLNODE *pNode;
+ register KAVLNODE *pParent;
+
+ KAVL_READ_LOCK(pRoot);
+
+ pParent = NULL;
+ pNode = KAVL_GET_POINTER_NULL(&pRoot->mpRoot);
+ while ( pNode != NULL
+ && KAVL_NE(pNode->mKey, Key))
+ {
+ pParent = pNode;
+ if (KAVL_G(pNode->mKey, Key))
+ pNode = KAVL_GET_POINTER_NULL(&pNode->mpLeft);
+ else
+ pNode = KAVL_GET_POINTER_NULL(&pNode->mpRight);
+ }
+
+ KAVL_READ_UNLOCK(pRoot);
+
+ *ppParent = pParent;
+ return pNode;
+}
+
diff --git a/src/lib/kStuff/include/k/kAvlTmpl/kAvlRemove2.h b/src/lib/kStuff/include/k/kAvlTmpl/kAvlRemove2.h
new file mode 100644
index 0000000..d027014
--- /dev/null
+++ b/src/lib/kStuff/include/k/kAvlTmpl/kAvlRemove2.h
@@ -0,0 +1,133 @@
+/* $Id: kAvlRemove2.h 34 2009-11-08 19:38:40Z bird $ */
+/** @file
+ * kAvlTmpl - Templated AVL Trees, Remove A Specific Node.
+ */
+
+/*
+ * Copyright (c) 1999-2009 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.
+ */
+
+/**
+ * Removes the specified node from the tree.
+ *
+ * @returns Pointer to the removed node (NULL if not in the tree)
+ * @param pRoot Pointer to the AVL-tree root structure.
+ * @param Key The Key of which is to be found a best fitting match for..
+ *
+ * @remark This implementation isn't the most efficient, but this short and
+ * easier to manage.
+ */
+KAVL_DECL(KAVLNODE *) KAVL_FN(Remove2)(KAVLROOT *pRoot, KAVLNODE *pNode)
+{
+#ifdef KAVL_EQUAL_ALLOWED
+ /*
+ * Find the right node by key and see if it's what we want.
+ */
+ KAVLNODE *pParent;
+ KAVLNODE *pCurNode = KAVL_FN(GetWithParent)(pRoot, pNode->mKey, &pParent);
+ if (!pCurNode)
+ return NULL;
+ KAVL_WRITE_LOCK(pRoot); /** @todo the locking here isn't 100% sane. The only way to archive that is by no calling worker functions. */
+ if (pCurNode != pNode)
+ {
+ /*
+ * It's not the one we want, but it could be in the duplicate list.
+ */
+ while (pCurNode->mpList != KAVL_NULL)
+ {
+ KAVLNODE *pNext = KAVL_GET_POINTER(&pCurNode->mpList);
+ if (pNext == pNode)
+ {
+ KAVL_SET_POINTER_NULL(&pCurNode->mpList, KAVL_GET_POINTER_NULL(&pNode->mpList));
+ pNode->mpList = KAVL_NULL;
+ KAVL_LOOKTHRU_INVALIDATE_NODE(pRoot, pNode, pNode->mKey);
+ KAVL_WRITE_UNLOCK(pRoot);
+ return pNode;
+ }
+ pCurNode = pNext;
+ }
+ KAVL_WRITE_UNLOCK(pRoot);
+ return NULL;
+ }
+
+ /*
+ * Ok, it's the one we want alright.
+ *
+ * Simply remove it if it's the only one with they Key,
+ * if there are duplicates we'll have to unlink it and
+ * insert the first duplicate in our place.
+ */
+ if (pNode->mpList == KAVL_NULL)
+ {
+ KAVL_WRITE_UNLOCK(pRoot);
+ KAVL_FN(Remove)(pRoot, pNode->mKey);
+ }
+ else
+ {
+ KAVLNODE *pNewUs = KAVL_GET_POINTER(&pNode->mpList);
+
+ pNewUs->mHeight = pNode->mHeight;
+
+ if (pNode->mpLeft != KAVL_NULL)
+ KAVL_SET_POINTER(&pNewUs->mpLeft, KAVL_GET_POINTER(&pNode->mpLeft))
+ else
+ pNewUs->mpLeft = KAVL_NULL;
+
+ if (pNode->mpRight != KAVL_NULL)
+ KAVL_SET_POINTER(&pNewUs->mpRight, KAVL_GET_POINTER(&pNode->mpRight))
+ else
+ pNewUs->mpRight = KAVL_NULL;
+
+ if (pParent)
+ {
+ if (KAVL_GET_POINTER_NULL(&pParent->mpLeft) == pNode)
+ KAVL_SET_POINTER(&pParent->mpLeft, pNewUs);
+ else
+ KAVL_SET_POINTER(&pParent->mpRight, pNewUs);
+ }
+ else
+ KAVL_SET_POINTER(&pRoot->mpRoot, pNewUs);
+
+ KAVL_LOOKTHRU_INVALIDATE_NODE(pRoot, pNode, pNode->mKey);
+ KAVL_WRITE_UNLOCK(pRoot);
+ }
+
+ return pNode;
+
+#else
+ /*
+ * Delete it, if we got the wrong one, reinsert it.
+ *
+ * This ASSUMS that the caller is NOT going to hand us a lot
+ * of wrong nodes but just uses this API for his convenience.
+ */
+ KAVLNODE *pRemovedNode = KAVL_FN(Remove)(pRoot, pNode->mKey);
+ if (pRemovedNode == pNode)
+ return pRemovedNode;
+
+ KAVL_FN(Insert)(pRoot, pRemovedNode);
+ return NULL;
+#endif
+}
+
diff --git a/src/lib/kStuff/include/k/kAvlTmpl/kAvlRemoveBestFit.h b/src/lib/kStuff/include/k/kAvlTmpl/kAvlRemoveBestFit.h
new file mode 100644
index 0000000..3c9ed98
--- /dev/null
+++ b/src/lib/kStuff/include/k/kAvlTmpl/kAvlRemoveBestFit.h
@@ -0,0 +1,70 @@
+/* $Id: kAvlRemoveBestFit.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kAvlTmpl - Templated AVL Trees, Remove Best Fitting Node.
+ */
+
+/*
+ * Copyright (c) 1999-2009 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.
+ */
+
+/**
+ * Finds the best fitting node in the tree for the given Key value and removes the node.
+ *
+ * @returns Pointer to the removed node.
+ * @param pRoot Pointer to the AVL-tree root structure.
+ * @param Key The Key of which is to be found a best fitting match for..
+ * @param fAbove K_TRUE: Returned node is have the closest key to Key from above.
+ * K_FALSE: Returned node is have the closest key to Key from below.
+ *
+ * @remark This implementation uses GetBestFit and then Remove and might therefore
+ * not be the most optimal kind of implementation, but it reduces the complexity
+ * code size, and the likelyhood for bugs.
+ */
+KAVL_DECL(KAVLNODE *) KAVL_FN(RemoveBestFit)(KAVLROOT *pRoot, KAVLKEY Key, KBOOL fAbove)
+{
+ /*
+ * If we find anything we'll have to remove the node and return it.
+ * Now, if duplicate keys are allowed we'll remove a duplicate before
+ * removing the in-tree node as this is way cheaper.
+ */
+ KAVLNODE *pNode = KAVL_FN(GetBestFit)(pRoot, Key, fAbove);
+ if (pNode != NULL)
+ {
+#ifdef KAVL_EQUAL_ALLOWED
+ KAVL_WRITE_LOCK(pRoot); /** @todo the locking isn't quite sane here. :-/ */
+ if (pNode->mpList != KAVL_NULL)
+ {
+ KAVLNODE *pRet = KAVL_GET_POINTER(&pNode->mpList);
+ KAVL_SET_POINTER_NULL(&pNode->mpList, &pRet->mpList);
+ KAVL_LOOKTHRU_INVALIDATE_NODE(pRoot, pNode, pNode->mKey);
+ KAVL_WRITE_UNLOCK(pRoot);
+ return pRet;
+ }
+ KAVL_WRITE_UNLOCK(pRoot);
+#endif
+ pNode = KAVL_FN(Remove)(pRoot, pNode->mKey);
+ }
+ return pNode;
+}
+
diff --git a/src/lib/kStuff/include/k/kAvlTmpl/kAvlUndef.h b/src/lib/kStuff/include/k/kAvlTmpl/kAvlUndef.h
new file mode 100644
index 0000000..bd6957f
--- /dev/null
+++ b/src/lib/kStuff/include/k/kAvlTmpl/kAvlUndef.h
@@ -0,0 +1,79 @@
+/* $Id: kAvlUndef.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kAvlTmpl - Undefines All Macros (both config and temp).
+ */
+
+/*
+ * 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.
+ */
+
+/*
+ * The configuration.
+ */
+#undef KAVL_EQUAL_ALLOWED
+#undef KAVL_CHECK_FOR_EQUAL_INSERT
+#undef KAVL_MAX_STACK
+#undef KAVL_RANGE
+#undef KAVL_OFFSET
+#undef KAVL_STD_KEY_COMP
+#undef KAVL_LOOKTHRU
+#undef KAVL_LOOKTHRU_HASH
+#undef KAVL_LOCKED
+#undef KAVL_WRITE_LOCK
+#undef KAVL_WRITE_UNLOCK
+#undef KAVL_READ_LOCK
+#undef KAVL_READ_UNLOCK
+#undef KAVLKEY
+#undef KAVLNODE
+#undef KAVLTREEPTR
+#undef KAVLROOT
+#undef KAVL_FN
+#undef KAVL_TYPE
+#undef KAVL_INT
+#undef KAVL_DECL
+#undef mKey
+#undef mKeyLast
+#undef mHeight
+#undef mpLeft
+#undef mpRight
+#undef mpList
+#undef mpRoot
+#undef maLookthru
+
+/*
+ * The internal macros.
+ */
+#undef KAVL_HEIGHTOF
+#undef KAVL_GET_POINTER
+#undef KAVL_GET_POINTER_NULL
+#undef KAVL_SET_POINTER
+#undef KAVL_SET_POINTER_NULL
+#undef KAVL_NULL
+#undef KAVL_G
+#undef KAVL_E
+#undef KAVL_NE
+#undef KAVL_R_IS_IDENTICAL
+#undef KAVL_R_IS_INTERSECTING
+#undef KAVL_R_IS_IN_RANGE
+
diff --git a/src/lib/kStuff/include/k/kAvlU32.h b/src/lib/kStuff/include/k/kAvlU32.h
new file mode 100644
index 0000000..7aacb15
--- /dev/null
+++ b/src/lib/kStuff/include/k/kAvlU32.h
@@ -0,0 +1,66 @@
+/* $Id: kAvlU32.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kAvl - AVL Tree Implementation, KU32 keys.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kAvlU32_h___
+#define ___k_kAvlU32_h___
+
+typedef struct KAVLU32
+{
+ KU32 mKey;
+ KU8 mHeight;
+ struct KAVLU32 *mpLeft;
+ struct KAVLU32 *mpRight;
+} KAVLU32, *PKAVLU32, **PPKAVLU32;
+
+/*#define KAVL_EQUAL_ALLOWED*/
+#define KAVL_CHECK_FOR_EQUAL_INSERT
+#define KAVL_MAX_STACK 32
+/*#define KAVL_RANGE */
+/*#define KAVL_OFFSET */
+#define KAVL_STD_KEY_COMP
+#define KAVLKEY KU32
+#define KAVLNODE KAVLU32
+#define KAVL_FN(name) kAvlU32 ## name
+#define KAVL_TYPE(prefix,name) prefix ## KAVLU32 ## name
+#define KAVL_INT(name) KAVLU32INT ## name
+#define KAVL_DECL(rettype) K_DECL_INLINE(rettype)
+
+#include <k/kAvlTmpl/kAvlBase.h>
+#include <k/kAvlTmpl/kAvlDoWithAll.h>
+#include <k/kAvlTmpl/kAvlEnum.h>
+#include <k/kAvlTmpl/kAvlGet.h>
+#include <k/kAvlTmpl/kAvlGetBestFit.h>
+#include <k/kAvlTmpl/kAvlGetWithParent.h>
+#include <k/kAvlTmpl/kAvlRemove2.h>
+#include <k/kAvlTmpl/kAvlRemoveBestFit.h>
+#include <k/kAvlTmpl/kAvlUndef.h>
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kAvloU32.h b/src/lib/kStuff/include/k/kAvloU32.h
new file mode 100644
index 0000000..e9ad305
--- /dev/null
+++ b/src/lib/kStuff/include/k/kAvloU32.h
@@ -0,0 +1,75 @@
+/* $Id: kAvloU32.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kAvl - AVL Tree Implementation, KU32 keys, Offset Based.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kAvloU32_h___
+#define ___k_kAvloU32_h___
+
+typedef KI32 KAVLOU32PTR;
+
+typedef struct KAVLOU32
+{
+ KU32 u32;
+ KU8 cFloorsToGo;
+ KAVLOU32PTR offLeft;
+ KAVLOU32PTR offRight;
+} KAVLOU32, *PKAVLOU32, **PPKAVLOU32;
+
+#define mKey u32
+#define mHeight cFloorsToGo
+#define mpLeft offLeft
+#define mpRight offRight
+
+/*#define KAVL_EQUAL_ALLOWED*/
+#define KAVL_CHECK_FOR_EQUAL_INSERT
+#define KAVL_MAX_STACK 32
+/*#define KAVL_RANGE */
+#define KAVL_OFFSET
+#define KAVL_STD_KEY_COMP
+#define KAVLKEY KU32
+#define KAVLTREEPTR KAVLOU32PTR
+#define KAVLNODE KAVLOU32
+#define KAVL_FN(name) kAvloU32 ## name
+#define KAVL_TYPE(prefix,name) prefix ## KAVLOU32 ## name
+#define KAVL_INT(name) KAVLOU32INT ## name
+#define KAVL_DECL(rettype) K_DECL_INLINE(rettype)
+
+#include <k/kAvlTmpl/kAvlBase.h>
+#include <k/kAvlTmpl/kAvlDoWithAll.h>
+#include <k/kAvlTmpl/kAvlEnum.h>
+#include <k/kAvlTmpl/kAvlGet.h>
+#include <k/kAvlTmpl/kAvlGetBestFit.h>
+#include <k/kAvlTmpl/kAvlGetWithParent.h>
+#include <k/kAvlTmpl/kAvlRemove2.h>
+#include <k/kAvlTmpl/kAvlRemoveBestFit.h>
+#include <k/kAvlTmpl/kAvlUndef.h>
+
+#endif
+
+
diff --git a/src/lib/kStuff/include/k/kAvlrU32.h b/src/lib/kStuff/include/k/kAvlrU32.h
new file mode 100644
index 0000000..532a55d
--- /dev/null
+++ b/src/lib/kStuff/include/k/kAvlrU32.h
@@ -0,0 +1,71 @@
+/* $Id: kAvlrU32.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kAvl - AVL Tree Implementation, KU32 key ranges.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kAvlrU32_h___
+#define ___k_kAvlrU32_h___
+
+typedef struct KAVLRU32
+{
+ KU32 u32Start;
+ KU32 u32Last;
+ struct KAVLRU32 *mpLeft;
+ struct KAVLRU32 *mpRight;
+ KU8 mHeight;
+} KAVLRU32, *PKAVLRU32, **PPKAVLRU32;
+
+#define mKey u32Start
+#define mKeyLast u32Last
+
+/*#define KAVL_EQUAL_ALLOWED*/
+#define KAVL_CHECK_FOR_EQUAL_INSERT
+#define KAVL_MAX_STACK 32
+#define KAVL_RANGE
+/*#define KAVL_OFFSET */
+#define KAVL_STD_KEY_COMP
+#define KAVLKEY KU32
+#define KAVLNODE KAVLRU32
+#define KAVL_FN(name) kAvlrU32 ## name
+#define KAVL_TYPE(prefix,name) prefix ## KAVLRU32 ## name
+#define KAVL_INT(name) KAVLRU32INT ## name
+#define KAVL_DECL(rettype) K_DECL_INLINE(rettype)
+
+#include <k/kAvlTmpl/kAvlBase.h>
+#include <k/kAvlTmpl/kAvlDoWithAll.h>
+#include <k/kAvlTmpl/kAvlEnum.h>
+#include <k/kAvlTmpl/kAvlGet.h>
+#include <k/kAvlTmpl/kAvlGetBestFit.h>
+#include <k/kAvlTmpl/kAvlGetWithParent.h>
+#include <k/kAvlTmpl/kAvlRemove2.h>
+#include <k/kAvlTmpl/kAvlRemoveBestFit.h>
+#include <k/kAvlTmpl/kAvlUndef.h>
+
+#endif
+
+
diff --git a/src/lib/kStuff/include/k/kCpu.h b/src/lib/kStuff/include/k/kCpu.h
new file mode 100644
index 0000000..bbbf815
--- /dev/null
+++ b/src/lib/kStuff/include/k/kCpu.h
@@ -0,0 +1,68 @@
+/* $Id: kCpu.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kCpu - The CPU and Architecture API.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kCpu_h___
+#define ___k_kCpu_h___
+
+#include <k/kDefs.h>
+#include <k/kTypes.h>
+#include <k/kCpus.h>
+
+
+/** @defgroup grp_kCpu kCpu - The CPU And Architecture API
+ * @{
+ */
+
+/** @def KCPU_DECL
+ * Declares a kCpu function according to build context.
+ * @param type The return type.
+ */
+#if defined(KCPU_BUILDING_DYNAMIC)
+# define KCPU_DECL(type) K_DECL_EXPORT(type)
+#elif defined(KCPU_BUILT_DYNAMIC)
+# define KCPU_DECL(type) K_DECL_IMPORT(type)
+#else
+# define KCPU_DECL(type) type
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+KCPU_DECL(void) kCpuGetArchAndCpu(PKCPUARCH penmArch, PKCPU penmCpu);
+KCPU_DECL(int) kCpuCompare(KCPUARCH enmCodeArch, KCPU enmCodeCpu, KCPUARCH enmArch, KCPU enmCpu);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif
diff --git a/src/lib/kStuff/include/k/kCpus.h b/src/lib/kStuff/include/k/kCpus.h
new file mode 100644
index 0000000..6fa8400
--- /dev/null
+++ b/src/lib/kStuff/include/k/kCpus.h
@@ -0,0 +1,157 @@
+/* $Id: kCpus.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kCpus - CPU Identifiers.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kCpus_h___
+#define ___k_kCpus_h___
+
+/** @defgroup grp_kCpus kCpus - CPU Identifiers
+ * @see the kCpu API for functions operating on the CPU type.
+ * @{
+ */
+
+/**
+ * CPU Architectures.
+ *
+ * The constants used by this enum has the same values as
+ * the K_ARCH_* #defines defined by k/kDefs.h.
+ */
+typedef enum KCPUARCH
+{
+ /** @copydoc K_ARCH_UNKNOWN */
+ KCPUARCH_UNKNOWN = K_ARCH_UNKNOWN,
+ /** @copydoc K_ARCH_X86_16 */
+ KCPUARCH_X86_16 = K_ARCH_X86_16,
+ /** @copydoc K_ARCH_X86_32 */
+ KCPUARCH_X86_32 = K_ARCH_X86_32,
+ /** @copydoc K_ARCH_AMD64 */
+ KCPUARCH_AMD64 = K_ARCH_AMD64,
+ /** @copydoc K_ARCH_IA64 */
+ KCPUARCH_IA64 = K_ARCH_IA64,
+ /** @copydoc K_ARCH_ALPHA */
+ KCPUARCH_ALPHA = K_ARCH_ALPHA,
+ /** @copydoc K_ARCH_ALPHA_32 */
+ KCPUARCH_ALPHA_32 = K_ARCH_ALPHA_32,
+ /** @copydoc K_ARCH_ARM_32 */
+ KCPUARCH_ARM_32 = K_ARCH_ARM_32,
+ /** @copydoc K_ARCH_ARM_64 */
+ KCPUARCH_ARM_64 = K_ARCH_ARM_64,
+ /** @copydoc K_ARCH_MIPS_32 */
+ KCPUARCH_MIPS_32 = K_ARCH_MIPS_32,
+ /** @copydoc K_ARCH_MIPS_64 */
+ KCPUARCH_MIPS_64 = K_ARCH_MIPS_64,
+ /** @copydoc K_ARCH_POWERPC_32 */
+ KCPUARCH_POWERPC_32 = K_ARCH_POWERPC_32,
+ /** @copydoc K_ARCH_POWERPC_64 */
+ KCPUARCH_POWERPC_64 = K_ARCH_POWERPC_64,
+ /** @copydoc K_ARCH_SPARC_32 */
+ KCPUARCH_SPARC_32 = K_ARCH_SPARC_32,
+ /** @copydoc K_ARCH_SPARC_64 */
+ KCPUARCH_SPARC_64 = K_ARCH_SPARC_64,
+
+ /** Hack to blow the type up to 32-bit. */
+ KCPUARCH_32BIT_HACK = 0x7fffffff
+} KCPUARCH;
+
+/** Pointer to a CPU architecture type. */
+typedef KCPUARCH *PKCPUARCH;
+/** Pointer to a const CPU architecture type. */
+typedef const KCPUARCH *PCKCPUARCH;
+
+
+/**
+ * CPU models.
+ */
+typedef enum KCPU
+{
+ /** The usual invalid cpu. */
+ KCPU_INVALID = 0,
+
+ /** @name K_ARCH_X86_16
+ * @{ */
+ KCPU_I8086,
+ KCPU_I8088,
+ KCPU_I80186,
+ KCPU_I80286,
+ KCPU_I386_16,
+ KCPU_I486_16,
+ KCPU_I486SX_16,
+ KCPU_I586_16,
+ KCPU_I686_16,
+ KCPU_P4_16,
+ KCPU_CORE2_16,
+ KCPU_K6_16,
+ KCPU_K7_16,
+ KCPU_K8_16,
+ KCPU_FIRST_X86_16 = KCPU_I8086,
+ KCPU_LAST_X86_16 = KCPU_K8_16,
+ /** @} */
+
+ /** @name K_ARCH_X86_32
+ * @{ */
+ KCPU_X86_32_BLEND,
+ KCPU_I386,
+ KCPU_I486,
+ KCPU_I486SX,
+ KCPU_I586,
+ KCPU_I686,
+ KCPU_P4,
+ KCPU_CORE2_32,
+ KCPU_K6,
+ KCPU_K7,
+ KCPU_K8_32,
+ KCPU_FIRST_X86_32 = KCPU_I386,
+ KCPU_LAST_X86_32 = KCPU_K8_32,
+ /** @} */
+
+ /** @name K_ARCH_AMD64
+ * @{ */
+ KCPU_AMD64_BLEND,
+ KCPU_K8,
+ KCPU_P4_64,
+ KCPU_CORE2,
+ KCPU_FIRST_AMD64 = KCPU_K8,
+ KCPU_LAST_AMD64 = KCPU_CORE2,
+ /** @} */
+
+ /** The end of the valid cpu values (exclusive). */
+ KCPU_END,
+ /** Hack to blow the type up to 32-bit. */
+ KCPU_32BIT_HACK = 0x7fffffff
+} KCPU;
+
+/** Pointer to a CPU type. */
+typedef KCPU *PKCPU;
+/** Pointer to a const CPU type. */
+typedef const KCPU *PCKCPU;
+
+/** @} */
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kDbg.h b/src/lib/kStuff/include/k/kDbg.h
new file mode 100644
index 0000000..07ee431
--- /dev/null
+++ b/src/lib/kStuff/include/k/kDbg.h
@@ -0,0 +1,243 @@
+/* $Id: kDbg.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kDbg - The Debug Info Reader.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kDbg_h___
+#define ___k_kDbg_h___
+
+#include <k/kDefs.h>
+#include <k/kTypes.h>
+#include <k/kRdr.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup grp_kDbg Debug Info Reader
+ * @{
+ */
+
+/** @def KDBG_DECL
+ * Declares a kDbg function according to build context.
+ * @param type The return type.
+ */
+#if defined(KDBG_BUILDING_DYNAMIC)
+# define KDBG_DECL(type) K_DECL_EXPORT(type)
+#elif defined(KDBG_BUILT_DYNAMIC)
+# define KDBG_DECL(type) K_DECL_IMPORT(type)
+#else
+# define KDBG_DECL(type) type
+#endif
+
+
+/** The kDbg address type. */
+typedef KU64 KDBGADDR;
+/** Pointer to a kDbg address. */
+typedef KDBGADDR *PKDBGADDR;
+/** Pointer to a const kDbg address. */
+typedef const KDBGADDR *PCKDBGADDR;
+/** @def KDBGADDR_PRI
+ * printf format type. */
+#define KDBGADDR_PRI KX64_PRI
+/** @def KDBGADDR_MAX
+ * Max kDbg address value. */
+#define KDBGADDR_MAX KU64_C(0xfffffffffffffffe)
+/** @def KDBGADDR_C
+ * kDbg address constant.
+ * @param c The constant value. */
+#define KDBGADDR_C(c) KU64_C(c)
+/** NIL address. */
+#define NIL_KDBGADDR KU64_MAX
+
+
+/** @name Special Segments
+ * @{ */
+/** Relative Virtual Address.
+ * The specified offset is relative to the image base. The image base is the lowest memory
+ * address used by the image when loaded with the address assignments indicated in the image. */
+#define KDBGSEG_RVA (-1)
+/** Absolute segment. The offset isn't relative to anything. */
+#define KDBGSEG_ABS (-2)
+/** @} */
+
+
+/** The max filename path length used by the debug reader. */
+#define KDBG_PATH_MAX 260
+
+/**
+ * Line number details.
+ */
+typedef struct KDBGLINE
+{
+ /** The relative virtual address. */
+ KDBGADDR RVA;
+ /** The offset into the segment. */
+ KDBGADDR offSegment;
+ /** The segment number. */
+ KI32 iSegment;
+ /** The Line number. */
+ KU32 iLine;
+ /** The actual size of this structure. */
+ KU16 cbSelf;
+ /** The length of the filename. */
+ KU16 cchFile;
+ /** The name of the file this line number relates to. */
+ char szFile[KDBG_PATH_MAX];
+} KDBGLINE;
+/** Pointer to line number details. */
+typedef KDBGLINE *PKDBGLINE;
+/** Pointer to const line number details. */
+typedef const KDBGLINE *PCKDBGLINE;
+/** Pointer to a pointer to line number details. */
+typedef PKDBGLINE *PPKDBGLINE;
+
+/**
+ * Duplicates a line number.
+ *
+ * To save heap space, the returned line number will not own more heap space
+ * than it strictly need to. So, it's not possible to append stuff to the symbol
+ * or anything of that kind.
+ *
+ * @returns Pointer to the duplicate.
+ * This must be freed using RTDbgSymbolFree().
+ * @param pLine The line number to be duplicated.
+ */
+KDBG_DECL(PKDBGLINE) kDbgLineDup(PCKDBGLINE pLine);
+
+/**
+ * Frees a line number obtained from the RTDbg API.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns KERR_INVALID_POINTER if a NULL pointer or an !KDBG_VALID_PTR() is passed in.
+ *
+ * @param pLine The line number to be freed.
+ */
+KDBG_DECL(int) kDbgLineFree(PKDBGLINE pLine);
+
+
+/** @name Symbol Flags.
+ * @{ */
+/** The symbol is weak. */
+#define KDBGSYM_FLAGS_WEAK KU32_C(0x00000000)
+/** The symbol is absolute.
+ * (This also indicated by the segment number.) */
+#define KDBGSYM_FLAGS_ABS KU32_C(0x00000001)
+/** The symbol is exported. */
+#define KDBGSYM_FLAGS_EXPORTED KU32_C(0x00000002)
+/** The symbol is a function/method/procedure/whatever-executable-code. */
+#define KDBGSYM_FLAGS_CODE KU32_C(0x00000004)
+/** The symbol is some kind of data. */
+#define KDBGSYM_FLAGS_DATA KU32_C(0x00000008)
+/** @} */
+
+/** The max symbol name length used by the debug reader. */
+#define KDBG_SYMBOL_MAX 384
+
+/**
+ * Symbol details.
+ */
+typedef struct KDBGSYMBOL
+{
+ /** The adddress of this symbol in the relevant space.
+ * This is NIL_KDBGADDR unless the information was
+ * returned by a kDbgSpace API. */
+ KDBGADDR Address;
+ /** The relative virtual address. */
+ KDBGADDR RVA;
+ /** The symbol size.
+ * This is not a reliable field, it could be a bad guess. Ignore if zero. */
+ KDBGADDR cb;
+ /** The offset into the segment. */
+ KDBGADDR offSegment;
+ /** The segment number. */
+ KI32 iSegment;
+ /** The symbol flags. */
+ KU32 fFlags;
+/** @todo type info. */
+ /** The actual size of this structure. */
+ KU16 cbSelf;
+ /** The length of the symbol name. */
+ KU16 cchName;
+ /** The symbol name. */
+ char szName[KDBG_SYMBOL_MAX];
+} KDBGSYMBOL;
+/** Pointer to symbol details. */
+typedef KDBGSYMBOL *PKDBGSYMBOL;
+/** Pointer to const symbol details. */
+typedef const KDBGSYMBOL *PCKDBGSYMBOL;
+/** Pointer to a pointer to symbol details. */
+typedef PKDBGSYMBOL *PPKDBGSYMBOL;
+
+/**
+ * Duplicates a symbol.
+ *
+ * To save heap space, the returned symbol will not own more heap space than
+ * it strictly need to. So, it's not possible to append stuff to the symbol
+ * or anything of that kind.
+ *
+ * @returns Pointer to the duplicate.
+ * This must be freed using kDbgSymbolFree().
+ * @param pSymbol The symbol to be freed.
+ */
+KDBG_DECL(PKDBGSYMBOL) kDbgSymbolDup(PCKDBGSYMBOL pSymbol);
+
+/**
+ * Frees a symbol obtained from the kDbg API.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns KERR_INVALID_POINTER if a NULL pointer or an !KDBG_VALID_PTR() is passed in.
+ *
+ * @param pSymbol The symbol to be freed.
+ */
+KDBG_DECL(int) kDbgSymbolFree(PKDBGSYMBOL pSymbol);
+
+
+/** Pointer to a debug module. */
+typedef struct KDBGMOD *PKDBGMOD;
+/** Pointer to a debug module pointer. */
+typedef PKDBGMOD *PPKDBGMOD;
+
+
+KDBG_DECL(int) kDbgModuleOpen(PPKDBGMOD ppDbgMod, const char *pszFilename, struct KLDRMOD *pLdrMod);
+KDBG_DECL(int) kDbgModuleOpenFile(PPKDBGMOD ppDbgMod, PKRDR pRdr, struct KLDRMOD *pLdrMod);
+KDBG_DECL(int) kDbgModuleOpenFilePart(PPKDBGMOD ppDbgMod, PKRDR pRdr, KFOFF off, KFOFF cb, struct KLDRMOD *pLdrMod);
+KDBG_DECL(int) kDbgModuleClose(PKDBGMOD pMod);
+KDBG_DECL(int) kDbgModuleQuerySymbol(PKDBGMOD pMod, KI32 iSegment, KDBGADDR off, PKDBGSYMBOL pSym);
+KDBG_DECL(int) kDbgModuleQuerySymbolA(PKDBGMOD pMod, KI32 iSegment, KDBGADDR off, PPKDBGSYMBOL ppSym);
+KDBG_DECL(int) kDbgModuleQueryLine(PKDBGMOD pMod, KI32 iSegment, KDBGADDR off, PKDBGLINE pLine);
+KDBG_DECL(int) kDbgModuleQueryLineA(PKDBGMOD pMod, KI32 iSegment, KDBGADDR off, PPKDBGLINE ppLine);
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/lib/kStuff/include/k/kDbgAll.h b/src/lib/kStuff/include/k/kDbgAll.h
new file mode 100644
index 0000000..fde7c0f
--- /dev/null
+++ b/src/lib/kStuff/include/k/kDbgAll.h
@@ -0,0 +1,168 @@
+/* $Id: kDbgAll.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kDbg - The Debug Info Read, All Details and Dependencies Included.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kDbgAll_h___
+#define ___k_kDbgAll_h___
+
+#include <k/kDefs.h>
+#include <k/kTypes.h>
+#include <k/kRdr.h>
+#include <k/kLdr.h>
+#include <k/kDbg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup grp_kDbgAll All
+ * @addtogroup grp_kDbg
+ * @{
+ */
+
+/**
+ * The debug module method table.
+ */
+typedef struct KDBGMODOPS
+{
+ /** The name of the reader. */
+ const char *pszName;
+
+ /** Pointer to the next debug module readers.
+ * This is only used for dynamically registered readers. */
+ struct KDBGMODOPS *pNext;
+
+ /**
+ * Tries to open the module.
+ *
+ * @returns 0 on success, KDBG_ERR on failure.
+ * @param ppMod Where to store the module that's been opened.
+ * @param pRdr The file provider.
+ * @param fCloseRdrs Whether the reader should be closed or not when the module is destroyed.
+ * @param off The file offset of the debug info. This is 0 if there isn't
+ * any specfic debug info section and the reader should start
+ * looking for debug info at the start of the file.
+ * @param cb The size of the debug info in the file. INT64_MAX if we don't
+ * know or there isn't any particular debug info section in the file.
+ * @param pLdrMod The associated loader module. This can be NULL.
+ */
+ int (*pfnOpen)(PKDBGMOD *ppMod, PKRDR pRdr, KBOOL fCloseRdr, KFOFF off, KFOFF cb, struct KLDRMOD *pLdrMod);
+
+ /**
+ * Closes the module.
+ *
+ * This should free all resources associated with the module
+ * except the pMod which is freed by the caller.
+ *
+ * @returns IPRT status code.
+ * @param pMod The module.
+ */
+ int (*pfnClose)(PKDBGMOD pMod);
+
+ /**
+ * Gets a symbol by segment:offset.
+ * This will be approximated to the nearest symbol if there is no exact match.
+ *
+ * @returns 0 on success. KLDR_ERR_* on failure.
+ * @param pMod The module.
+ * @param iSegment The segment this offset is relative to.
+ * The -1 segment is special, it means that the addres is relative to
+ * the image base. The image base is where the first bit of the image
+ * is mapped during load.
+ * @param off The offset into the segment.
+ * @param pSym Where to store the symbol details.
+ */
+ int (*pfnQuerySymbol)(PKDBGMOD pMod, KI32 iSegment, KDBGADDR off, PKDBGSYMBOL pSym);
+
+ /**
+ * Gets a line number entry by segment:offset.
+ * This will be approximated to the nearest line number there is no exact match.
+ *
+ * @returns 0 on success. KLDR_ERR_* on failure.
+ * @param pMod The module.
+ * @param iSegment The segment this offset is relative to.
+ * The -1 segment is special, it means that the addres is relative to
+ * the image base. The image base is where the first bit of the image
+ * is mapped during load.
+ * @param off The offset into the segment.
+ * @param pLine Where to store the line number details.
+ */
+ int (*pfnQueryLine)(PKDBGMOD pMod, KI32 iSegment, KDBGADDR uOffset, PKDBGLINE pLine);
+
+ /** This is just to make sure you've initialized all the fields.
+ * Must be identical to pszName. */
+ const char *pszName2;
+} KDBGMODOPS;
+/** Pointer to a module method table. */
+typedef KDBGMODOPS *PKDBGMODOPS;
+/** Pointer to a const module method table. */
+typedef const KDBGMODOPS *PCKDBGMODOPS;
+
+/**
+ * Register a debug module reader with the kDbgModule component.
+ *
+ * Dynamically registered readers are kept in FIFO order, and external
+ * readers will be tried after the builtin ones.
+ *
+ * @returns 0 on success.
+ * @returns KERR_INVALID_POINTER if pOps is missing bits.
+ * @returns KERR_INVALID_PARAMETER if pOps is already in the list.
+ * @param pOps The reader method table, kDbg takes owner ship of
+ * this. This must be writeable as the pNext pointer
+ * will be update. It must also stick around for as
+ * long as kDbg is in use.
+ */
+KDBG_DECL(int) kDbgModuleRegisterReader(PKDBGMODOPS pOps);
+
+
+
+/**
+ * Internal representation of a debug module.
+ */
+typedef struct KDBGMOD
+{
+ /** Magic value (KDBGMOD_MAGIC). */
+ KI32 u32Magic;
+ /** Pointer to the method table. */
+ PCKDBGMODOPS pOps;
+ /** The file provider for the file containing the debug info. */
+ PKRDR pRdr;
+ /** Whether or not to close pRdr. */
+ KBOOL fCloseRdr;
+ /** The associated kLdr module. This may be NULL. */
+ PKLDRMOD pLdrMod;
+} KDBGMOD;
+
+/** @}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/lib/kStuff/include/k/kDbgBase.h b/src/lib/kStuff/include/k/kDbgBase.h
new file mode 100644
index 0000000..5ae31fb
--- /dev/null
+++ b/src/lib/kStuff/include/k/kDbgBase.h
@@ -0,0 +1,248 @@
+/* $Id: kDbgBase.h 40 2010-02-02 16:02:15Z bird $ */
+/** @file
+ * kDbg - The Debug Info Reader, Base Definitions and Typedefs.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___kDbgBase_h___
+#define ___kDbgBase_h___
+
+#include <k/kDefs.h>
+#include <k/kTypes.h>
+
+
+/** @defgroup grp_kDbgBase kDbgBase - Base Definitions And Typedefs
+ * @{ */
+
+/*
+ * kDbg depend on size_t, [u]intNN_t, [u]intptr_t and some related constants.
+ * If KDBG_ALREADY_INCLUDED_STD_TYPES or KCOMMON_ALREADY_INCLUDED_STD_TYPES
+ * is defined, these has already been defined.
+ */
+#if !defined(KDBG_ALREADY_INCLUDED_STD_TYPES) && !defined(KCOMMON_ALREADY_INCLUDED_STD_TYPES)
+# define KCOMMON_ALREADY_INCLUDED_STD_TYPES 1
+# include <sys/types.h>
+# include <stddef.h>
+# ifdef _MSC_VER
+ typedef signed char int8_t;
+ typedef unsigned char uint8_t;
+ typedef signed short int16_t;
+ typedef unsigned short uint16_t;
+ typedef signed int int32_t;
+ typedef unsigned int uint32_t;
+ typedef signed __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
+ typedef int64_t intmax_t;
+ typedef uint64_t uintmax_t;
+# define UINT8_C(c) (c)
+# define UINT16_C(c) (c)
+# define UINT32_C(c) (c ## U)
+# define UINT64_C(c) (c ## ULL)
+# define INT8_C(c) (c)
+# define INT16_C(c) (c)
+# define INT32_C(c) (c)
+# define INT64_C(c) (c ## LL)
+# define INT8_MIN (INT8_C(-0x7f) - 1)
+# define INT16_MIN (INT16_C(-0x7fff) - 1)
+# define INT32_MIN (INT32_C(-0x7fffffff) - 1)
+# define INT64_MIN (INT64_C(-0x7fffffffffffffff) - 1)
+# define INT8_MAX INT8_C(0x7f)
+# define INT16_MAX INT16_C(0x7fff)
+# define INT32_MAX INT32_C(0x7fffffff)
+# define INT64_MAX INT64_C(0x7fffffffffffffff)
+# define UINT8_MAX UINT8_C(0xff)
+# define UINT16_MAX UINT16_C(0xffff)
+# define UINT32_MAX UINT32_C(0xffffffff)
+# define UINT64_MAX UINT64_C(0xffffffffffffffff)
+# else
+# include <stdint.h>
+# endif
+#endif /* !KDBG_ALREADY_INCLUDED_STD_TYPES && !KCOMMON_ALREADY_INCLUDED_STD_TYPES */
+
+
+/** @def KDBG_CALL
+ * The calling convention used by the kDbg functions. */
+#if defined(_MSC_VER) || defined(__OS2__)
+# define KDBG_CALL __cdecl
+#else
+# define KDBG_CALL
+#endif
+
+#ifdef DOXYGEN_RUNNING
+/** @def KDBG_BUILDING
+ * Define KDBG_BUILDING to indicate that kDbg is being built.
+ */
+# define KDBG_BUILDING
+/** @def KDBG_RESIDES_IN_DLL
+ * Define KDBG_RESIDES_IN_DLL to indicate that kDbg resides in a DLL.
+ */
+# define KDBG_RESIDES_IN_DLL
+#endif
+
+/** @def KDBG_DECL
+ * Macro for defining public functions. */
+#if defined(KDBG_RESIDES_IN_DLL) \
+ && (defined(_MSC_VER) || defined(__OS2__))
+# ifdef KDBG_BUILDING
+# define KDBG_DECL(type) __declspec(dllexport) type
+# else
+# define KDBG_DECL(type) __declspec(dllimport) type
+# endif
+#else
+# define KDBG_DECL(type) type
+#endif
+
+/** @def KDBG_INLINE
+ * Macro for defining an inline function. */
+#ifdef __cplusplus
+# if defined(__GNUC__)
+# define KDBG_INLINE(type) static inline type
+# else
+# define KDBG_INLINE(type) inline type
+# endif
+#else
+# if defined(__GNUC__)
+# define KDBG_INLINE(type) static __inline__ type
+# elif defined(_MSC_VER)
+# define KDBG_INLINE(type) _inline type
+# else
+# error "Port me"
+# endif
+#endif
+
+
+/** The kDbg address type. */
+typedef uint64_t KDBGADDR;
+/** Pointer to a kLdr address. */
+typedef KDBGADDR *PKDBGADDR;
+/** Pointer to a const kLdr address. */
+typedef const KDBGADDR *PCKDBGADDR;
+
+/** NIL address. */
+#define NIL_KDBGADDR (~(uint64_t)0)
+
+/** @def PRI_KDBGADDR
+ * printf format type. */
+#ifdef _MSC_VER
+# define PRI_KDBGADDR "I64x"
+#else
+# define PRI_KDBGADDR "llx"
+#endif
+
+
+/** Get the minimum of two values. */
+#define KDBG_MIN(a, b) ((a) <= (b) ? (a) : (b))
+/** Get the maximum of two values. */
+#define KDBG_MAX(a, b) ((a) >= (b) ? (a) : (b))
+/** Calculate the offset of a structure member. */
+#define KDBG_OFFSETOF(strct, memb) ( (size_t)( &((strct *)0)->memb ) )
+/** Align a size_t value. */
+#define KDBG_ALIGN_Z(val, align) ( ((val) + ((align) - 1)) & ~(size_t)((align) - 1) )
+/** Align a void * value. */
+#define KDBG_ALIGN_P(pv, align) ( (void *)( ((uintptr_t)(pv) + ((align) - 1)) & ~(uintptr_t)((align) - 1) ) )
+/** Align a size_t value. */
+#define KDBG_ALIGN_ADDR(val, align) ( ((val) + ((align) - 1)) & ~(KDBGADDR)((align) - 1) )
+/** Number of elements in an array. */
+#define KDBG_ELEMENTS(a) ( sizeof(a) / sizeof((a)[0]) )
+/** @def KDBG_VALID_PTR
+ * Checks if the specified pointer is a valid address or not. */
+#define KDBG_VALID_PTR(ptr) ( (uintptr_t)(ptr) + 0x1000U >= 0x2000U )
+
+
+/** @def KDBG_LITTLE_ENDIAN
+ * The kDbg build is for a little endian target. */
+/** @def KDBG_BIG_ENDIAN
+ * The kDbg build is for a big endian target. */
+#if !defined(KDBG_LITTLE_ENDIAN) && !defined(KDBG_BIG_ENDIAN)
+# define KDBG_LITTLE_ENDIAN
+#endif
+#ifdef DOXYGEN_RUNNING
+# define KDBG_BIG_ENDIAN
+#endif
+
+
+/** @name Endian Conversion
+ * @{ */
+
+/** @def KDBG_E2E_U16
+ * Convert the endian of an unsigned 16-bit value. */
+# define KDBG_E2E_U16(u16) ( (uint16_t) (((u16) >> 8) | ((u16) << 8)) )
+/** @def KDBG_E2E_U32
+ * Convert the endian of an unsigned 32-bit value. */
+# define KDBG_E2E_U32(u32) ( ( ((u32) & UINT32_C(0xff000000)) >> 24 ) \
+ | ( ((u32) & UINT32_C(0x00ff0000)) >> 8 ) \
+ | ( ((u32) & UINT32_C(0x0000ff00)) << 8 ) \
+ | ( ((u32) & UINT32_C(0x000000ff)) << 24 ) \
+ )
+/** @def KDBG_E2E_U64
+ * Convert the endian of an unsigned 64-bit value. */
+# define KDBG_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 KDBG_LE2H_U16
+ * Unsigned 16-bit little-endian to host endian. */
+/** @def KDBG_LE2H_U32
+ * Unsigned 32-bit little-endian to host endian. */
+/** @def KDBG_LE2H_U64
+ * Unsigned 64-bit little-endian to host endian. */
+/** @def KDBG_BE2H_U16
+ * Unsigned 16-bit big-endian to host endian. */
+/** @def KDBG_BE2H_U32
+ * Unsigned 32-bit big-endian to host endian. */
+/** @def KDBG_BE2H_U64
+ * Unsigned 64-bit big-endian to host endian. */
+#ifdef KDBG_LITTLE_ENDIAN
+# define KDBG_LE2H_U16(u16) ((uint16_t)(u16))
+# define KDBG_LE2H_U32(u32) ((uint32_t)(u32))
+# define KDBG_LE2H_U64(u64) ((uint32_t)(u32))
+# define KDBG_BE2H_U16(u16) KDBG_E2E_U16(u16)
+# define KDBG_BE2H_U32(u32) KDBG_E2E_U32(u32)
+# define KDBG_BE2H_U64(u64) KDBG_E2E_U64(u64)
+#elif defined(KDBG_BIG_ENDIAN)
+# define KDBG_LE2H_U16(u16) KDBG_E2E_U16(u16)
+# define KDBG_LE2H_U32(u32) KDBG_E2E_U32(u32)
+# define KDBG_LE2H_U32(u64) KDBG_E2E_U64(u64)
+# define KDBG_BE2H_U16(u16) ((uint16_t)(u16))
+# define KDBG_BE2H_U32(u32) ((uint32_t)(u32))
+# define KDBG_BE2H_U64(u64) ((uint32_t)(u32))
+#else
+# error "KDBG_BIG_ENDIAN or KDBG_LITTLE_ENDIAN is supposed to be defined."
+#endif
+
+/** @} */
+
+/** @} */
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kDefs.h b/src/lib/kStuff/include/k/kDefs.h
new file mode 100644
index 0000000..ffa1cf2
--- /dev/null
+++ b/src/lib/kStuff/include/k/kDefs.h
@@ -0,0 +1,596 @@
+/* $Id: kDefs.h 120 2022-02-18 02:00:53Z bird $ */
+/** @file
+ * kTypes - Defines and Macros.
+ */
+
+/*
+ * Copyright (c) 2006-2017 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.
+ */
+
+#ifndef ___k_kDefs_h___
+#define ___k_kDefs_h___
+
+/** @defgroup grp_kDefs kDefs - Defines and Macros
+ * @{ */
+
+/** @name Operative System Identifiers.
+ * These are the value that the K_OS \#define can take.
+ * @{
+ */
+/** Unknown OS. */
+#define K_OS_UNKNOWN 0
+/** Darwin - aka Mac OS X. */
+#define K_OS_DARWIN 1
+/** DragonFly BSD. */
+#define K_OS_DRAGONFLY 2
+/** FreeBSD. */
+#define K_OS_FREEBSD 3
+/** GNU/Hurd. */
+#define K_OS_GNU_HURD 4
+/** GNU/kFreeBSD. */
+#define K_OS_GNU_KFBSD 5
+/** GNU/kNetBSD or GNU/NetBSD or whatever the decide to call it. */
+#define K_OS_GNU_KNBSD 6
+/** Haiku. */
+#define K_OS_HAIKU 7
+/** Linux. */
+#define K_OS_LINUX 8
+/** NetBSD. */
+#define K_OS_NETBSD 9
+/** NT (native). */
+#define K_OS_NT 10
+/** OpenBSD*/
+#define K_OS_OPENBSD 11
+/** OS/2 */
+#define K_OS_OS2 12
+/** Solaris */
+#define K_OS_SOLARIS 13
+/** Windows. */
+#define K_OS_WINDOWS 14
+/** The max K_OS_* value (exclusive). */
+#define K_OS_MAX 15
+/** @} */
+
+/** @def K_OS
+ * Indicates which OS we're targetting. It's a \#define with is
+ * assigned one of the K_OS_* defines above.
+ *
+ * So to test if we're on FreeBSD do the following:
+ * @code
+ * #if K_OS == K_OS_FREEBSD
+ * some_funky_freebsd_specific_stuff();
+ * #endif
+ * @endcode
+ */
+#ifndef K_OS
+# if defined(__APPLE__)
+# define K_OS K_OS_DARWIN
+# elif defined(__DragonFly__)
+# define K_OS K_OS_DRAGONFLY
+# elif defined(__FreeBSD__)
+# define K_OS K_OS_FREEBSD
+# elif defined(__FreeBSD_kernel__)
+# define K_OS K_OS_GNU_KFBSD
+# elif defined(__gnu_hurd__)
+# define K_OS K_OS_GNU_HURD
+# elif defined(__gnu_linux__)
+# define K_OS K_OS_LINUX
+# elif defined(__NetBSD__) /*??*/
+# define K_OS K_OS_NETBSD
+# elif defined(__NetBSD_kernel__)
+# define K_OS K_OS_GNU_KNBSD
+# elif defined(__OpenBSD__) /*??*/
+# define K_OS K_OS_OPENBSD
+# elif defined(__OS2__)
+# define K_OS K_OS_OS2
+# elif defined(__sun__) || defined(__SunOS__) || defined(__sun) || defined(__SunOS)
+# define K_OS K_OS_SOLARIS
+# elif defined(_WIN32) || defined(_WIN64)
+# define K_OS K_OS_WINDOWS
+# elif defined(__haiku__) || defined(__HAIKU__)
+# define K_OS K_OS_HAIKU
+# else
+# error "Port Me"
+# endif
+#endif
+#if K_OS < K_OS_UNKNOWN || K_OS >= K_OS_MAX
+# error "Invalid K_OS value."
+#endif
+
+
+
+/** @name Architecture bit width.
+ * @{ */
+#define K_ARCH_BIT_8 0x0100 /**< 8-bit */
+#define K_ARCH_BIT_16 0x0200 /**< 16-bit */
+#define K_ARCH_BIT_32 0x0400 /**< 32-bit */
+#define K_ARCH_BIT_64 0x0800 /**< 64-bit */
+#define K_ARCH_BIT_128 0x1000 /**< 128-bit */
+#define K_ARCH_BIT_MASK 0x1f00 /**< The bit mask. */
+#define K_ARCH_BIT_SHIFT 5 /**< Shift count for producing the width in bits. */
+#define K_ARCH_BYTE_SHIFT 8 /**< Shift count for producing the width in bytes. */
+/** @} */
+
+/** @name Architecture Endianness.
+ * @{ */
+#define K_ARCH_END_LITTLE 0x2000 /**< Little-endian. */
+#define K_ARCH_END_BIG 0x4000 /**< Big-endian. */
+#define K_ARCH_END_BI 0x6000 /**< Bi-endian, can be switched. */
+#define K_ARCH_END_MASK 0x6000 /**< The endian mask. */
+#define K_ARCH_END_SHIFT 13 /**< Shift count for converting between this K_ENDIAN_*. */
+/** @} */
+
+/** @name Architecture Identifiers.
+ * These are the value that the K_ARCH \#define can take.
+ *@{ */
+/** Unknown CPU architecture. */
+#define K_ARCH_UNKNOWN ( 0 )
+/** Clone or Intel 16-bit x86. */
+#define K_ARCH_X86_16 ( 1 | K_ARCH_BIT_16 | K_ARCH_END_LITTLE)
+/** Clone or Intel 32-bit x86. */
+#define K_ARCH_X86_32 ( 1 | K_ARCH_BIT_32 | K_ARCH_END_LITTLE)
+/** AMD64 (including clones). */
+#define K_ARCH_AMD64 ( 2 | K_ARCH_BIT_64 | K_ARCH_END_LITTLE)
+/** Itanic (64-bit). */
+#define K_ARCH_IA64 ( 3 | K_ARCH_BIT_64 | K_ARCH_END_BI)
+/** ALPHA (64-bit). */
+#define K_ARCH_ALPHA ( 4 | K_ARCH_BIT_64 | K_ARCH_END_BI)
+/** ALPHA limited to 32-bit. */
+#define K_ARCH_ALPHA_32 ( 4 | K_ARCH_BIT_32 | K_ARCH_END_BI)
+/** 32-bit ARM. */
+#define K_ARCH_ARM_32 ( 5 | K_ARCH_BIT_32 | K_ARCH_END_BI)
+/** 64-bit ARM. */
+#define K_ARCH_ARM_64 ( 5 | K_ARCH_BIT_64 | K_ARCH_END_BI)
+/** Motorola 68000 (32-bit). */
+#define K_ARCH_M68K ( 6 | K_ARCH_BIT_32 | K_ARCH_END_BIG)
+/** 32-bit MIPS. */
+#define K_ARCH_MIPS_32 ( 7 | K_ARCH_BIT_32 | K_ARCH_END_BI)
+/** 64-bit MIPS. */
+#define K_ARCH_MIPS_64 ( 7 | K_ARCH_BIT_64 | K_ARCH_END_BI)
+/** 32-bit PA-RISC. */
+#define K_ARCH_PARISC_32 ( 8 | K_ARCH_BIT_32 | K_ARCH_END_BI)
+/** 64-bit PA-RISC. */
+#define K_ARCH_PARISC_64 ( 8 | K_ARCH_BIT_64 | K_ARCH_END_BI)
+/** 32-bit PowerPC. */
+#define K_ARCH_POWERPC_32 ( 9 | K_ARCH_BIT_32 | K_ARCH_END_BI)
+/** 64-bit PowerPC. */
+#define K_ARCH_POWERPC_64 ( 9 | K_ARCH_BIT_64 | K_ARCH_END_BI)
+/** 32(31)-bit S390. */
+#define K_ARCH_S390_32 (10 | K_ARCH_BIT_32 | K_ARCH_END_BIG)
+/** 64-bit S390. */
+#define K_ARCH_S390_64 (10 | K_ARCH_BIT_64 | K_ARCH_END_BIG)
+/** 32-bit SuperH. */
+#define K_ARCH_SH_32 (11 | K_ARCH_BIT_32 | K_ARCH_END_BI)
+/** 64-bit SuperH. */
+#define K_ARCH_SH_64 (11 | K_ARCH_BIT_64 | K_ARCH_END_BI)
+/** 32-bit SPARC. */
+#define K_ARCH_SPARC_32 (12 | K_ARCH_BIT_32 | K_ARCH_END_BIG)
+/** 64-bit SPARC. */
+#define K_ARCH_SPARC_64 (12 | K_ARCH_BIT_64 | K_ARCH_END_BI)
+/** 32-bit RISC-V, little endian. */
+#define K_ARCH_RISCV_32 (13 | K_ARCH_BIT_32 | K_ARCH_END_LITTLE)
+/** 32-bit RISC-V, big endian. */
+#define K_ARCH_RISCV_32_BE (13 | K_ARCH_BIT_32 | K_ARCH_END_BIG)
+/** 64-bit RISC-V, little endian. */
+#define K_ARCH_RISCV_64 (13 | K_ARCH_BIT_64 | K_ARCH_END_LITTLE)
+/** 64-bit RISC-V, big endian. */
+#define K_ARCH_RISCV_64_BE (13 | K_ARCH_BIT_64 | K_ARCH_END_BIG)
+/** The end of the valid architecture values (exclusive). */
+#define K_ARCH_MAX (12+1)
+/** @} */
+
+
+/** @def K_ARCH
+ * The value of this \#define indicates which architecture we're targetting.
+ */
+#ifndef K_ARCH
+ /* detection based on compiler defines. */
+# if defined(__amd64__) || defined(__x86_64__) || defined(__AMD64__) || defined(_M_X64) || defined(__amd64)
+# define K_ARCH K_ARCH_AMD64
+# elif defined(__i386__) || defined(__x86__) || defined(__X86__) || defined(_M_IX86) || defined(__i386)
+# define K_ARCH K_ARCH_X86_32
+# elif defined(__ia64__) || defined(__IA64__) || defined(_M_IA64)
+# define K_ARCH K_ARCH_IA64
+# elif defined(__alpha__)
+# define K_ARCH K_ARCH_ALPHA
+# elif defined(__arm__) || defined(__arm32__)
+# define K_ARCH K_ARCH_ARM_32
+# elif defined(__aarch64__) || defined(__arm64__)
+# define K_ARCH K_ARCH_ARM_64
+# elif defined(__hppa__) && defined(__LP64__)
+# define K_ARCH K_ARCH_PARISC_64
+# elif defined(__hppa__)
+# define K_ARCH K_ARCH_PARISC_32
+# elif defined(__m68k__)
+# define K_ARCH K_ARCH_M68K
+# elif defined(__mips64)
+# define K_ARCH K_ARCH_MIPS_64
+# elif defined(__mips__)
+# define K_ARCH K_ARCH_MIPS_32
+# elif defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__)
+# define K_ARCH K_ARCH_POWERPC_64
+# elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__)
+# define K_ARCH K_ARCH_POWERPC_32
+# elif defined(__riscv)
+# if __BYTE_ORDER__ == WORDS_BIG_ENDIAN
+# if defined(__riscv32) || __riscv_xlen+0 == 32
+# define K_ARCH K_ARCH_RISCV_32_BE
+# else
+# define K_ARCH K_ARCH_RISCV_64_BE
+# endif
+# elif defined(__riscv32) || __riscv_xlen+0 == 32
+# define K_ARCH K_ARCH_RISCV_32
+# else
+# define K_ARCH K_ARCH_RISCV_64
+# endif
+# elif defined(__sparcv9__) || defined(__sparcv9)
+# define K_ARCH K_ARCH_SPARC_64
+# elif defined(__sparc__) || defined(__sparc)
+# define K_ARCH K_ARCH_SPARC_32
+# elif defined(__s390x__)
+# define K_ARCH K_ARCH_S390_64
+# elif defined(__s390__)
+# define K_ARCH K_ARCH_S390_32
+# elif defined(__sh__)
+# if !defined(__SH5__)
+# define K_ARCH K_ARCH_SH_32
+# else
+# if __SH5__ == 64
+# define K_ARCH K_ARCH_SH_64
+# else
+# define K_ARCH K_ARCH_SH_32
+# endif
+# endif
+# else
+# error "Port Me"
+# endif
+#else
+ /* validate the user specified value. */
+# if (K_ARCH & K_ARCH_BIT_MASK) != K_ARCH_BIT_8 \
+ && (K_ARCH & K_ARCH_BIT_MASK) != K_ARCH_BIT_16 \
+ && (K_ARCH & K_ARCH_BIT_MASK) != K_ARCH_BIT_32 \
+ && (K_ARCH & K_ARCH_BIT_MASK) != K_ARCH_BIT_64 \
+ && (K_ARCH & K_ARCH_BIT_MASK) != K_ARCH_BIT_128
+# error "Invalid K_ARCH value (bit)"
+# endif
+# if (K_ARCH & K_ARCH_END_MASK) != K_ARCH_END_LITTLE \
+ && (K_ARCH & K_ARCH_END_MASK) != K_ARCH_END_BIG \
+ && (K_ARCH & K_ARCH_END_MASK) != K_ARCH_END_BI
+# error "Invalid K_ARCH value (endian)"
+# endif
+# if (K_ARCH & ~(K_ARCH_BIT_MASK | K_ARCH_BIT_END_MASK)) < K_ARCH_UNKNOWN \
+ || (K_ARCH & ~(K_ARCH_BIT_MASK | K_ARCH_BIT_END_MASK)) >= K_ARCH_MAX
+# error "Invalid K_ARCH value"
+# endif
+#endif
+
+/** @def K_ARCH_IS_VALID
+ * Check if the architecture identifier is valid.
+ * @param arch The K_ARCH_* define to examin.
+ */
+#define K_ARCH_IS_VALID(arch) ( ( ((arch) & K_ARCH_BIT_MASK) == K_ARCH_BIT_8 \
+ || ((arch) & K_ARCH_BIT_MASK) == K_ARCH_BIT_16 \
+ || ((arch) & K_ARCH_BIT_MASK) == K_ARCH_BIT_32 \
+ || ((arch) & K_ARCH_BIT_MASK) == K_ARCH_BIT_64 \
+ || ((arch) & K_ARCH_BIT_MASK) == K_ARCH_BIT_128) \
+ && \
+ ( ((arch) & K_ARCH_END_MASK) == K_ARCH_END_LITTLE \
+ || ((arch) & K_ARCH_END_MASK) == K_ARCH_END_BIG \
+ || ((arch) & K_ARCH_END_MASK) == K_ARCH_END_BI) \
+ && \
+ ( ((arch) & ~(K_ARCH_BIT_MASK | K_ARCH_END_MASK)) >= K_ARCH_UNKNOWN \
+ && ((arch) & ~(K_ARCH_BIT_MASK | K_ARCH_END_MASK)) < K_ARCH_MAX) \
+ )
+
+/** @def K_ARCH_BITS_EX
+ * Determin the architure byte width of the specified architecture.
+ * @param arch The K_ARCH_* define to examin.
+ */
+#define K_ARCH_BITS_EX(arch) ( ((arch) & K_ARCH_BIT_MASK) >> K_ARCH_BIT_SHIFT )
+
+/** @def K_ARCH_BYTES_EX
+ * Determin the architure byte width of the specified architecture.
+ * @param arch The K_ARCH_* define to examin.
+ */
+#define K_ARCH_BYTES_EX(arch) ( ((arch) & K_ARCH_BIT_MASK) >> K_ARCH_BYTE_SHIFT )
+
+/** @def K_ARCH_ENDIAN_EX
+ * Determin the K_ENDIAN value for the specified architecture.
+ * @param arch The K_ARCH_* define to examin.
+ */
+#define K_ARCH_ENDIAN_EX(arch) ( ((arch) & K_ARCH_END_MASK) >> K_ARCH_END_SHIFT )
+
+/** @def K_ARCH_BITS
+ * Determin the target architure bit width.
+ */
+#define K_ARCH_BITS K_ARCH_BITS_EX(K_ARCH)
+
+/** @def K_ARCH_BYTES
+ * Determin the target architure byte width.
+ */
+#define K_ARCH_BYTES K_ARCH_BYTES_EX(K_ARCH)
+
+/** @def K_ARCH_ENDIAN
+ * Determin the target K_ENDIAN value.
+ */
+#define K_ARCH_ENDIAN K_ARCH_ENDIAN_EX(K_ARCH)
+
+
+
+/** @name Endianness Identifiers.
+ * These are the value that the K_ENDIAN \#define can take.
+ * @{ */
+#define K_ENDIAN_LITTLE 1 /**< Little-endian. */
+#define K_ENDIAN_BIG 2 /**< Big-endian. */
+#define K_ENDIAN_BI 3 /**< Bi-endian, can be switched. Only used with K_ARCH. */
+/** @} */
+
+/** @def K_ENDIAN
+ * The value of this \#define indicates the target endianness.
+ *
+ * @remark It's necessary to define this (or add the necessary deduction here)
+ * on bi-endian architectures.
+ */
+#ifndef K_ENDIAN
+ /* use K_ARCH if possible. */
+# if K_ARCH_ENDIAN != K_ENDIAN_BI
+# define K_ENDIAN K_ARCH_ENDIAN
+# elif defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__)
+# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+# define K_ENDIAN K_ENDIAN_LITTLE
+# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+# define K_ENDIAN K_ENDIAN_BIG
+# else
+# error "Port Me or define K_ENDIAN."
+# endif
+# else
+# error "Port Me or define K_ENDIAN."
+# endif
+#else
+ /* validate the user defined value. */
+# if K_ENDIAN != K_ENDIAN_LITTLE \
+ && K_ENDIAN != K_ENDIAN_BIG
+# error "K_ENDIAN must either be defined as K_ENDIAN_LITTLE or as K_ENDIAN_BIG."
+# endif
+#endif
+
+/** @name Endian Conversion
+ * @{ */
+
+/** @def K_E2E_U16
+ * Convert the endian of an unsigned 16-bit value. */
+# define K_E2E_U16(u16) ( (KU16) (((u16) >> 8) | ((u16) << 8)) )
+/** @def K_E2E_U32
+ * Convert the endian of an unsigned 32-bit value. */
+# define K_E2E_U32(u32) ( ( ((u32) & KU32_C(0xff000000)) >> 24 ) \
+ | ( ((u32) & KU32_C(0x00ff0000)) >> 8 ) \
+ | ( ((u32) & KU32_C(0x0000ff00)) << 8 ) \
+ | ( ((u32) & KU32_C(0x000000ff)) << 24 ) \
+ )
+/** @def K_E2E_U64
+ * Convert the endian of an unsigned 64-bit value. */
+# define K_E2E_U64(u64) ( ( ((u64) & KU64_C(0xff00000000000000)) >> 56 ) \
+ | ( ((u64) & KU64_C(0x00ff000000000000)) >> 40 ) \
+ | ( ((u64) & KU64_C(0x0000ff0000000000)) >> 24 ) \
+ | ( ((u64) & KU64_C(0x000000ff00000000)) >> 8 ) \
+ | ( ((u64) & KU64_C(0x00000000ff000000)) << 8 ) \
+ | ( ((u64) & KU64_C(0x0000000000ff0000)) << 24 ) \
+ | ( ((u64) & KU64_C(0x000000000000ff00)) << 40 ) \
+ | ( ((u64) & KU64_C(0x00000000000000ff)) << 56 ) \
+ )
+
+/** @def K_LE2H_U16
+ * Unsigned 16-bit little-endian to host endian. */
+/** @def K_LE2H_U32
+ * Unsigned 32-bit little-endian to host endian. */
+/** @def K_LE2H_U64
+ * Unsigned 64-bit little-endian to host endian. */
+/** @def K_BE2H_U16
+ * Unsigned 16-bit big-endian to host endian. */
+/** @def K_BE2H_U32
+ * Unsigned 32-bit big-endian to host endian. */
+/** @def K_BE2H_U64
+ * Unsigned 64-bit big-endian to host endian. */
+#if K_ENDIAN == K_ENDIAN_LITTLE
+# define K_LE2H_U16(u16) ((KU16)(u16))
+# define K_LE2H_U32(u32) ((KU32)(u32))
+# define K_LE2H_U64(u64) ((KU64)(u32))
+# define K_BE2H_U16(u16) K_E2E_U16(u16)
+# define K_BE2H_U32(u32) K_E2E_U32(u32)
+# define K_BE2H_U64(u64) K_E2E_U64(u64)
+#else
+# define K_LE2H_U16(u16) K_E2E_U16(u16)
+# define K_LE2H_U32(u32) K_E2E_U32(u32)
+# define K_LE2H_U64(u64) K_E2E_U64(u64)
+# define K_BE2H_U16(u16) ((KU16)(u16))
+# define K_BE2H_U32(u32) ((KU32)(u32))
+# define K_BE2H_U64(u64) ((KU64)(u32))
+#endif
+
+
+
+/** @def K_INLINE
+ * How to say 'inline' in both C and C++ dialects.
+ * @param type The return type.
+ */
+#ifdef __cplusplus
+# if defined(__GNUC__)
+# define K_INLINE static inline
+# else
+# define K_INLINE inline
+# endif
+#else
+# if defined(__GNUC__)
+# define K_INLINE static __inline__
+# elif defined(_MSC_VER)
+# define K_INLINE static __inline
+# else
+# error "Port Me"
+# endif
+#endif
+
+/** @def K_EXPORT
+ * What to put in front of an exported function.
+ */
+#if K_OS == K_OS_OS2 || K_OS == K_OS_WINDOWS
+# define K_EXPORT __declspec(dllexport)
+#else
+# define K_EXPORT
+#endif
+
+/** @def K_IMPORT
+ * What to put in front of an imported function.
+ */
+#if K_OS == K_OS_OS2 || K_OS == K_OS_WINDOWS
+# define K_IMPORT __declspec(dllimport)
+#else
+# define K_IMPORT extern
+#endif
+
+/** @def K_DECL_EXPORT
+ * Declare an exported function.
+ * @param type The return type.
+ */
+#define K_DECL_EXPORT(type) K_EXPORT type
+
+/** @def K_DECL_IMPORT
+ * Declare an import function.
+ * @param type The return type.
+ */
+#define K_DECL_IMPORT(type) K_IMPORT type
+
+/** @def K_DECL_INLINE
+ * Declare an inline function.
+ * @param type The return type.
+ * @remark Don't use on (class) methods.
+ */
+#define K_DECL_INLINE(type) K_INLINE type
+
+
+/** Get the minimum of two values. */
+#define K_MIN(a, b) ( (a) <= (b) ? (a) : (b) )
+/** Get the maximum of two values. */
+#define K_MAX(a, b) ( (a) >= (b) ? (a) : (b) )
+/** Calculate the offset of a structure member. */
+#define K_OFFSETOF(strct, memb) ( (KSIZE)( &((strct *)0)->memb ) )
+/** Align a size_t value. */
+#define K_ALIGN_Z(val, align) ( ((val) + ((align) - 1)) & ~(KSIZE)((align) - 1) )
+/** Align a void * value. */
+#define K_ALIGN_P(pv, align) ( (void *)( ((KUPTR)(pv) + ((align) - 1)) & ~(KUPTR)((align) - 1) ) )
+/** Number of elements in an array. */
+#define K_ELEMENTS(a) ( sizeof(a) / sizeof((a)[0]) )
+/** Checks if the specified pointer is a valid address or not. */
+#define K_VALID_PTR(ptr) ( (KUPTR)(ptr) + 0x1000U >= 0x2000U )
+/** Makes a 32-bit bit mask. */
+#define K_BIT32(bit) ( KU32_C(1) << (bit))
+/** Makes a 64-bit bit mask. */
+#define K_BIT64(bit) ( KU64_C(1) << (bit))
+/** Shuts up unused parameter and unused variable warnings. */
+#define K_NOREF(var) ( (void)(var) )
+
+
+/** @name Parameter validation macros
+ * @{ */
+
+/** Return/Crash validation of a string argument. */
+#define K_VALIDATE_STRING(str) \
+ do { \
+ if (!K_VALID_PTR(str)) \
+ return KERR_INVALID_POINTER; \
+ kHlpStrLen(str); \
+ } while (0)
+
+/** Return/Crash validation of an optional string argument. */
+#define K_VALIDATE_OPTIONAL_STRING(str) \
+ do { \
+ if (str) \
+ K_VALIDATE_STRING(str); \
+ } while (0)
+
+/** Return/Crash validation of an output buffer. */
+#define K_VALIDATE_BUFFER(buf, cb) \
+ do { \
+ if (!K_VALID_PTR(buf)) \
+ return KERR_INVALID_POINTER; \
+ if ((cb) != 0) \
+ { \
+ KU8 __b; \
+ KU8 volatile *__pb = (KU8 volatile *)(buf); \
+ KSIZE __cbPage1 = 0x1000 - ((KUPTR)(__pb) & 0xfff); /* ASSUMES page size! */ \
+ __b = *__pb; *__pb = 0xff; *__pb = __b; \
+ if ((cb) > __cbPage1) \
+ { \
+ KSIZE __cb = (cb) - __cbPage1; \
+ __pb -= __cbPage1; \
+ for (;;) \
+ { \
+ __b = *__pb; *__pb = 0xff; *__pb = __b; \
+ if (__cb < 0x1000) \
+ break; \
+ __pb += 0x1000; \
+ __cb -= 0x1000; \
+ } \
+ } \
+ } \
+ else \
+ return KERR_INVALID_PARAMETER; \
+ } while (0)
+
+/** Return/Crash validation of an optional output buffer. */
+#define K_VALIDATE_OPTIONAL_BUFFER(buf, cb) \
+ do { \
+ if ((buf) && (cb) != 0) \
+ K_VALIDATE_BUFFER(buf, cb); \
+ } while (0)
+
+/** Return validation of an enum argument. */
+#define K_VALIDATE_ENUM(arg, enumname) \
+ do { \
+ if ((arg) <= enumname##_INVALID || (arg) >= enumname##_END) \
+ return KERR_INVALID_PARAMETER; \
+ } while (0)
+
+/** Return validation of a flags argument. */
+#define K_VALIDATE_FLAGS(arg, AllowedMask) \
+ do { \
+ if ((arg) & ~(AllowedMask)) \
+ return KERR_INVALID_PARAMETER; \
+ } while (0)
+
+/** @} */
+
+/** @def NULL
+ * The nil pointer value. */
+#ifndef NULL
+# ifdef __cplusplus
+# define NULL 0
+# else
+# define NULL ((void *)0)
+# endif
+#endif
+
+/** @} */
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kErr.h b/src/lib/kStuff/include/k/kErr.h
new file mode 100644
index 0000000..f183ef4
--- /dev/null
+++ b/src/lib/kStuff/include/k/kErr.h
@@ -0,0 +1,68 @@
+/* $Id: kErr.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kErr - Status Code API.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kErr_h___
+#define ___k_kErr_h___
+
+/** @defgroup grp_kErr kErr - Status Code API
+ * @{
+ */
+
+/** @def KERR_DECL
+ * Declares a kRdr function according to build context.
+ * @param type The return type.
+ */
+#if defined(KERR_BUILDING_DYNAMIC)
+# define KERR_DECL(type) K_DECL_EXPORT(type)
+#elif defined(KRDR_BUILT_DYNAMIC)
+# define KERR_DECL(type) K_DECL_IMPORT(type)
+#else
+# define KERR_DECL(type) type
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+KERR_DECL(const char *) kErrName(int rc);
+KERR_DECL(int) kErrFromErrno(int);
+KERR_DECL(int) kErrFromOS2(unsigned long rcOs2);
+KERR_DECL(int) kErrFromNtStatus(long rcNtStatus);
+KERR_DECL(int) kErrFromMach(int rcMach);
+KERR_DECL(int) kErrFromDarwin(int rcDarwin);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kErrors.h b/src/lib/kStuff/include/k/kErrors.h
new file mode 100644
index 0000000..be179ce
--- /dev/null
+++ b/src/lib/kStuff/include/k/kErrors.h
@@ -0,0 +1,327 @@
+/* $Id: kErrors.h 58 2013-10-12 20:18:21Z bird $ */
+/** @file
+ * kErrors - Status Codes.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kErrors_h___
+#define ___k_kErrors_h___
+
+/** @defgroup grp_kErrors Status Codes.
+ * @{
+ */
+/** The base of the kErrors status codes. */
+#define KERR_BASE 42000
+
+/** @name General
+ * @{
+ */
+/** The base of the general status codes. */
+#define KERR_GENERAL_BASE (KERR_BASE)
+/** Generic error. */
+#define KERR_GENERAL_FAILURE (KERR_GENERAL_BASE + 1)
+/** Out of memory. */
+#define KERR_NO_MEMORY (KERR_GENERAL_BASE + 2)
+/** Hit some unimplemented functionality - feel free to implement it :-) . */
+#define KERR_NOT_IMPLEMENTED (KERR_GENERAL_BASE + 3)
+/** An environment variable wasn't found. */
+#define KERR_ENVVAR_NOT_FOUND (KERR_GENERAL_BASE + 4)
+/** Buffer overflow. */
+#define KERR_BUFFER_OVERFLOW (KERR_GENERAL_BASE + 5)
+/** @}*/
+
+/** @name Input Validation
+ * @{
+ */
+/** The base of the input validation status codes. */
+#define KERR_INPUT_BASE (KERR_GENERAL_BASE + 6)
+/** An API was given an invalid parameter. */
+#define KERR_INVALID_PARAMETER (KERR_INPUT_BASE + 0)
+/** A pointer argument is not valid. */
+#define KERR_INVALID_POINTER (KERR_INPUT_BASE + 1)
+/** A handle argument is not valid. */
+#define KERR_INVALID_HANDLE (KERR_INPUT_BASE + 2)
+/** An offset argument is not valid. */
+#define KERR_INVALID_OFFSET (KERR_INPUT_BASE + 3)
+/** A size argument is not valid. */
+#define KERR_INVALID_SIZE (KERR_INPUT_BASE + 4)
+/** A range argument is not valid. */
+#define KERR_INVALID_RANGE (KERR_INPUT_BASE + 5)
+/** A parameter is out of range. */
+#define KERR_OUT_OF_RANGE (KERR_INPUT_BASE + 6)
+/** @} */
+
+/** @name File System and I/O
+ * @{
+ */
+/** The base of the file system and I/O status cdoes. */
+#define KERR_FILE_SYSTEM_AND_IO_BASE (KERR_INPUT_BASE + 7)
+/** The specified file was not found. */
+#define KERR_FILE_NOT_FOUND (KERR_FILE_SYSTEM_AND_IO_BASE + 0)
+/** End of file. */
+#define KERR_EOF (KERR_FILE_SYSTEM_AND_IO_BASE + 1)
+/** @} */
+
+/** @name kDbg Specific
+ * @{
+ */
+/** The base of the kDbg specific status codes. */
+#define KDBG_ERR_BASE (KERR_FILE_SYSTEM_AND_IO_BASE + 2)
+/** The (module) format isn't known to use. */
+#define KDBG_ERR_UNKOWN_FORMAT (KDBG_ERR_BASE + 0)
+/** The (module) format isn't supported by this kDbg build. */
+#define KDBG_ERR_FORMAT_NOT_SUPPORTED (KDBG_ERR_BASE + 1)
+/** The (module) format isn't supported by this kDbg build. */
+#define KDBG_ERR_BAD_EXE_FORMAT (KDBG_ERR_BASE + 2)
+/** A specified address or an address found in the debug info is invalid. */
+#define KDBG_ERR_INVALID_ADDRESS (KDBG_ERR_BASE + 3)
+/** The dbghelp.dll is too old or something like that. */
+#define KDBG_ERR_DBGHLP_VERSION_MISMATCH (KDBG_ERR_BASE + 4)
+/** @} */
+
+/** @name kRdr Specific
+ * @{
+ */
+/** the base of the kRdr specific status codes. */
+#define KRDR_ERR_BASE (KDBG_ERR_BASE + 5)
+/** The file reader can't take more concurrent mappings. */
+#define KRDR_ERR_TOO_MANY_MAPPINGS (KRDR_ERR_BASE + 0)
+/** The pRdr instance passed to a kRdrBuf* API isn't a buffered instance. */
+#define KRDR_ERR_NOT_BUFFERED_RDR (KRDR_ERR_BASE + 1)
+/** The line is too long to fit in the buffer passed to kRdrBufLine or kRdrBufLineEx. */
+#define KRDR_ERR_LINE_TOO_LONG (KRDR_ERR_BASE + 2)
+/** @} */
+
+/** @name kLdr Specific
+ * @{
+ */
+/** The base of the kLdr specific status codes. */
+#define KLDR_ERR_BASE (KRDR_ERR_BASE + 3)
+
+/** The image format is unknown. */
+#define KLDR_ERR_UNKNOWN_FORMAT (KLDR_ERR_BASE + 0)
+/** The MZ image format isn't supported by this kLdr build. */
+#define KLDR_ERR_MZ_NOT_SUPPORTED (KLDR_ERR_BASE + 1)
+/** The NE image format isn't supported by this kLdr build. */
+#define KLDR_ERR_NE_NOT_SUPPORTED (KLDR_ERR_BASE + 2)
+/** The LX image format isn't supported by this kLdr build. */
+#define KLDR_ERR_LX_NOT_SUPPORTED (KLDR_ERR_BASE + 3)
+/** The LE image format isn't supported by this kLdr build. */
+#define KLDR_ERR_LE_NOT_SUPPORTED (KLDR_ERR_BASE + 4)
+/** The PE image format isn't supported by this kLdr build. */
+#define KLDR_ERR_PE_NOT_SUPPORTED (KLDR_ERR_BASE + 5)
+/** The ELF image format isn't supported by this kLdr build. */
+#define KLDR_ERR_ELF_NOT_SUPPORTED (KLDR_ERR_BASE + 6)
+/** The mach-o image format isn't supported by this kLdr build. */
+#define KLDR_ERR_MACHO_NOT_SUPPORTED (KLDR_ERR_BASE + 7)
+/** 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)
+
+/** The module wasn't loaded dynamically. */
+#define KLDR_ERR_NOT_LOADED_DYNAMICALLY (KLDR_ERR_BASE + 10)
+/** The module wasn't found. */
+#define KLDR_ERR_MODULE_NOT_FOUND (KLDR_ERR_BASE + 11)
+/** A prerequisit module wasn't found. */
+#define KLDR_ERR_PREREQUISITE_MODULE_NOT_FOUND (KLDR_ERR_BASE + 12)
+/** The module is being terminated and can therefore not be loaded. */
+#define KLDR_ERR_MODULE_TERMINATING (KLDR_ERR_BASE + 13)
+/** A prerequisit module is being terminated and can therefore not be loaded. */
+#define KLDR_ERR_PREREQUISITE_MODULE_TERMINATING (KLDR_ERR_BASE + 14)
+/** The module initialization failed. */
+#define KLDR_ERR_MODULE_INIT_FAILED (KLDR_ERR_BASE + 15)
+/** The initialization of a prerequisite module failed. */
+#define KLDR_ERR_PREREQUISITE_MODULE_INIT_FAILED (KLDR_ERR_BASE + 16)
+/** The module has already failed initialization and can't be attempted reloaded until
+ * after we've finished garbage collection. */
+#define KLDR_ERR_MODULE_INIT_FAILED_ALREADY (KLDR_ERR_BASE + 17)
+/** A prerequisite module has already failed initialization and can't be attempted
+ * reloaded until after we've finished garbage collection. */
+#define KLDR_ERR_PREREQUISITE_MODULE_INIT_FAILED_ALREADY (KLDR_ERR_BASE + 18)
+/** Prerequisite recursed too deeply. */
+#define KLDR_ERR_PREREQUISITE_RECURSED_TOO_DEEPLY (KLDR_ERR_BASE + 19)
+/** Failed to allocate the main stack. */
+#define KLDR_ERR_MAIN_STACK_ALLOC_FAILED (KLDR_ERR_BASE + 20)
+/** Symbol not found. */
+#define KLDR_ERR_SYMBOL_NOT_FOUND (KLDR_ERR_BASE + 21)
+/** A forward symbol was encountered but the caller didn't provide any means to resolve it. */
+#define KLDR_ERR_FORWARDER_SYMBOL (KLDR_ERR_BASE + 22)
+/** Encountered a bad fixup. */
+#define KLDR_ERR_BAD_FIXUP (KLDR_ERR_BASE + 23)
+/** The import ordinal was out of bounds. */
+#define KLDR_ERR_IMPORT_ORDINAL_OUT_OF_BOUNDS (KLDR_ERR_BASE + 24)
+/** A forwarder chain was too long. */
+#define KLDR_ERR_TOO_LONG_FORWARDER_CHAIN (KLDR_ERR_BASE + 25)
+/** The module has no debug info. */
+#define KLDR_ERR_NO_DEBUG_INFO (KLDR_ERR_BASE + 26)
+/** The module is already mapped.
+ * kLdrModMap() can only be called once (without kLdrModUnmap() in between). */
+#define KLDR_ERR_ALREADY_MAPPED (KLDR_ERR_BASE + 27)
+/** The module was not mapped.
+ * kLdrModUnmap() should not called without being preceeded by a kLdrModMap(). */
+#define KLDR_ERR_NOT_MAPPED (KLDR_ERR_BASE + 28)
+/** Couldn't fit the address value into the field. Typically a relocation kind of error. */
+#define KLDR_ERR_ADDRESS_OVERFLOW (KLDR_ERR_BASE + 29)
+/** Couldn't fit a calculated size value into the native size type of the host. */
+#define KLDR_ERR_SIZE_OVERFLOW (KLDR_ERR_BASE + 30)
+/** Thread attach failed. */
+#define KLDR_ERR_THREAD_ATTACH_FAILED (KLDR_ERR_BASE + 31)
+/** The module wasn't a DLL or object file. */
+#define KLDR_ERR_NOT_DLL (KLDR_ERR_BASE + 32)
+/** The module wasn't an EXE. */
+#define KLDR_ERR_NOT_EXE (KLDR_ERR_BASE + 33)
+/** Not implemented yet. */
+#define KLDR_ERR_TODO (KLDR_ERR_BASE + 34)
+/** No image matching the requested CPU. */
+#define KLDR_ERR_CPU_ARCH_MISMATCH (KLDR_ERR_BASE + 35)
+/** Invalid FAT image header. */
+#define KLDR_ERR_FAT_INVALID (KLDR_ERR_BASE + 36)
+/** Unsupported CPU subtype found in a FAT entry. */
+#define KLDR_ERR_FAT_UNSUPPORTED_CPU_SUBTYPE (KLDR_ERR_BASE + 37)
+/** The image has no UUID. */
+#define KLDR_ERR_NO_IMAGE_UUID (KLDR_ERR_BASE + 38)
+/** Duplicate segment name. */
+#define KLDR_ERR_DUPLICATE_SEGMENT_NAME (KLDR_ERR_BASE + 39)
+/** @} */
+
+/** @name kLdrModPE Specific
+ * @{
+ */
+/** The base of the kLdrModPE specific status codes. */
+#define KLDR_ERR_PE_BASE (KLDR_ERR_BASE + 40)
+/** The machine isn't supported by the interpreter. */
+#define KLDR_ERR_PE_UNSUPPORTED_MACHINE (KLDR_ERR_PE_BASE + 0)
+/** The file handler isn't valid. */
+#define KLDR_ERR_PE_BAD_FILE_HEADER (KLDR_ERR_PE_BASE + 1)
+/** The the optional headers isn't valid. */
+#define KLDR_ERR_PE_BAD_OPTIONAL_HEADER (KLDR_ERR_PE_BASE + 2)
+/** One of the section headers aren't valid. */
+#define KLDR_ERR_PE_BAD_SECTION_HEADER (KLDR_ERR_PE_BASE + 3)
+/** Bad forwarder entry. */
+#define KLDR_ERR_PE_BAD_FORWARDER (KLDR_ERR_PE_BASE + 4)
+/** Forwarder module not found in the import descriptor table. */
+#define KLDR_ERR_PE_FORWARDER_IMPORT_NOT_FOUND (KLDR_ERR_PE_BASE + 5)
+/** Bad PE fixups. */
+#define KLDR_ERR_PE_BAD_FIXUP (KLDR_ERR_PE_BASE + 6)
+/** Bad PE import (thunk). */
+#define KLDR_ERR_PE_BAD_IMPORT (KLDR_ERR_PE_BASE + 7)
+/** @} */
+
+/** @name kLdrModLX Specific
+ * @{
+ */
+/** The base of the kLdrModLX specific status codes. */
+#define KLDR_ERR_LX_BASE (KLDR_ERR_PE_BASE + 8)
+/** validation of LX header failed. */
+#define KLDR_ERR_LX_BAD_HEADER (KLDR_ERR_LX_BASE + 0)
+/** validation of the loader section (in the LX header) failed. */
+#define KLDR_ERR_LX_BAD_LOADER_SECTION (KLDR_ERR_LX_BASE + 1)
+/** validation of the fixup section (in the LX header) failed. */
+#define KLDR_ERR_LX_BAD_FIXUP_SECTION (KLDR_ERR_LX_BASE + 2)
+/** validation of the LX object table failed. */
+#define KLDR_ERR_LX_BAD_OBJECT_TABLE (KLDR_ERR_LX_BASE + 3)
+/** A bad page map entry was encountered. */
+#define KLDR_ERR_LX_BAD_PAGE_MAP (KLDR_ERR_LX_BASE + 4)
+/** Bad iterdata (EXEPACK) data. */
+#define KLDR_ERR_LX_BAD_ITERDATA (KLDR_ERR_LX_BASE + 5)
+/** Bad iterdata2 (EXEPACK2) data. */
+#define KLDR_ERR_LX_BAD_ITERDATA2 (KLDR_ERR_LX_BASE + 6)
+/** Bad bundle data. */
+#define KLDR_ERR_LX_BAD_BUNDLE (KLDR_ERR_LX_BASE + 7)
+/** No soname. */
+#define KLDR_ERR_LX_NO_SONAME (KLDR_ERR_LX_BASE + 8)
+/** Bad soname. */
+#define KLDR_ERR_LX_BAD_SONAME (KLDR_ERR_LX_BASE + 9)
+/** Bad forwarder entry. */
+#define KLDR_ERR_LX_BAD_FORWARDER (KLDR_ERR_LX_BASE + 10)
+/** internal fixup chain isn't implemented yet. */
+#define KLDR_ERR_LX_NRICHAIN_NOT_SUPPORTED (KLDR_ERR_LX_BASE + 11)
+/** @} */
+
+/** @name kLdrModMachO Specific
+ * @{
+ */
+/** The base of the kLdrModMachO specific status codes. */
+#define KLDR_ERR_MACHO_BASE (KLDR_ERR_LX_BASE + 12)
+/** Only native endian Mach-O files are supported. */
+#define KLDR_ERR_MACHO_OTHER_ENDIAN_NOT_SUPPORTED (KLDR_ERR_MACHO_BASE + 0)
+/** The Mach-O header is bad or contains new and unsupported features. */
+#define KLDR_ERR_MACHO_BAD_HEADER (KLDR_ERR_MACHO_BASE + 1)
+/** The file type isn't supported. */
+#define KLDR_ERR_MACHO_UNSUPPORTED_FILE_TYPE (KLDR_ERR_MACHO_BASE + 2)
+/** The machine (cputype / cpusubtype combination) isn't supported. */
+#define KLDR_ERR_MACHO_UNSUPPORTED_MACHINE (KLDR_ERR_MACHO_BASE + 3)
+/** Bad load command(s). */
+#define KLDR_ERR_MACHO_BAD_LOAD_COMMAND (KLDR_ERR_MACHO_BASE + 4)
+/** Encountered an unknown load command.*/
+#define KLDR_ERR_MACHO_UNKNOWN_LOAD_COMMAND (KLDR_ERR_MACHO_BASE + 5)
+/** Encountered a load command that's not implemented.*/
+#define KLDR_ERR_MACHO_UNSUPPORTED_LOAD_COMMAND (KLDR_ERR_MACHO_BASE + 6)
+/** Bad section. */
+#define KLDR_ERR_MACHO_BAD_SECTION (KLDR_ERR_MACHO_BASE + 7)
+/** Encountered a section type that's not implemented.*/
+#define KLDR_ERR_MACHO_UNSUPPORTED_SECTION (KLDR_ERR_MACHO_BASE + 8)
+/** Encountered a init function section. */
+#define KLDR_ERR_MACHO_UNSUPPORTED_INIT_SECTION (KLDR_ERR_MACHO_BASE + 9)
+/** Encountered a term function section. */
+#define KLDR_ERR_MACHO_UNSUPPORTED_TERM_SECTION (KLDR_ERR_MACHO_BASE + 10)
+/** Encountered a section type that's not known to the loader. (probably invalid) */
+#define KLDR_ERR_MACHO_UNKNOWN_SECTION (KLDR_ERR_MACHO_BASE + 11)
+/** The sections aren't ordered by segment as expected by the loader. */
+#define KLDR_ERR_MACHO_BAD_SECTION_ORDER (KLDR_ERR_MACHO_BASE + 12)
+/** The image is 32-bit and contains 64-bit load commands or vise versa. */
+#define KLDR_ERR_MACHO_BIT_MIX (KLDR_ERR_MACHO_BASE + 13)
+/** Bad MH_OBJECT file. */
+#define KLDR_ERR_MACHO_BAD_OBJECT_FILE (KLDR_ERR_MACHO_BASE + 14)
+/** Bad symbol table entry. */
+#define KLDR_ERR_MACHO_BAD_SYMBOL (KLDR_ERR_MACHO_BASE + 15)
+/** Unsupported fixup type. */
+#define KLDR_ERR_MACHO_UNSUPPORTED_FIXUP_TYPE (KLDR_ERR_MACHO_BASE + 16)
+/** Both debug and non-debug sections in segment. */
+#define KLDR_ERR_MACHO_MIXED_DEBUG_SECTION_FLAGS (KLDR_ERR_MACHO_BASE + 17)
+/** The segment bits are non-contiguous in the file. */
+#define KLDR_ERR_MACHO_NON_CONT_SEG_BITS (KLDR_ERR_MACHO_BASE + 18)
+/** @} */
+
+/** @name kCpu Specific
+ * @{
+ */
+/** The base of the kCpu specific status codes. */
+#define KCPU_ERR_BASE (KLDR_ERR_MACHO_BASE + 19)
+/** The specified ARCH+CPU pairs aren't compatible. */
+#define KCPU_ERR_ARCH_CPU_NOT_COMPATIBLE (KCPU_ERR_BASE + 0)
+/** @} */
+
+/** End of the valid status codes. */
+#define KERR_END (KCPU_ERR_BASE + 1)
+/** @}*/
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kHlp.h b/src/lib/kStuff/include/k/kHlp.h
new file mode 100644
index 0000000..7e83b85
--- /dev/null
+++ b/src/lib/kStuff/include/k/kHlp.h
@@ -0,0 +1,53 @@
+/* $Id: kHlp.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kHlp - Helpers, All Of Them.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kHlp_h___
+#define ___k_kHlp_h___
+
+#include <k/kDefs.h>
+#include <k/kTypes.h>
+#include <k/kErrors.h>
+#include <k/kHlpAlloc.h>
+#include <k/kHlpAssert.h>
+#include <k/kHlpEnv.h>
+#include <k/kHlpPath.h>
+#include <k/kHlpProcess.h>
+#include <k/kHlpSem.h>
+#include <k/kHlpString.h>
+#include <k/kHlpThread.h>
+
+/** @defgroup grp_kHlp kHlp - Helper Functions
+ * @{ */
+
+/** @} */
+
+#endif
+
+
diff --git a/src/lib/kStuff/include/k/kHlpAlloc.h b/src/lib/kStuff/include/k/kHlpAlloc.h
new file mode 100644
index 0000000..99ae8b6
--- /dev/null
+++ b/src/lib/kStuff/include/k/kHlpAlloc.h
@@ -0,0 +1,78 @@
+/* $Id: kHlpAlloc.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kHlpAlloc - Memory Allocation.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kHlpAlloc_h___
+#define ___k_kHlpAlloc_h___
+
+#include <k/kHlpDefs.h>
+#include <k/kTypes.h>
+
+/** @defgroup grp_kHlpAlloc kHlpAlloc - Memory Allocation
+ * @addtogroup grp_kHlp
+ * @{*/
+
+/** @def kHlpAllocA
+ * The alloca() wrapper. */
+#ifdef __GNUC__
+# define kHlpAllocA(a) __builtin_alloca(a)
+#elif defined(_MSC_VER)
+# include <malloc.h>
+# define kHlpAllocA(a) alloca(a)
+#else
+# error "Port Me."
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+KHLP_DECL(void *) kHlpAlloc(KSIZE cb);
+KHLP_DECL(void *) kHlpAllocZ(KSIZE cb);
+KHLP_DECL(void *) kHlpDup(const void *pv, KSIZE cb);
+KHLP_DECL(char *) kHlpStrDup(const char *psz);
+KHLP_DECL(void *) kHlpRealloc(void *pv, KSIZE cb);
+KHLP_DECL(void) kHlpFree(void *pv);
+
+KHLP_DECL(int) kHlpPageAlloc(void **ppv, KSIZE cb, KPROT enmProt, KBOOL fFixed);
+KHLP_DECL(int) kHlpPageProtect(void *pv, KSIZE cb, KPROT enmProt);
+KHLP_DECL(int) kHlpPageFree(void *pv, KSIZE cb);
+
+KHLP_DECL(int) kHlpHeapInit(void);
+KHLP_DECL(void) kHlpHeapTerm(void);
+KHLP_DECL(void) kHlpHeapDonate(void *pv, KSIZE cb);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kHlpAssert.h b/src/lib/kStuff/include/k/kHlpAssert.h
new file mode 100644
index 0000000..45105d1
--- /dev/null
+++ b/src/lib/kStuff/include/k/kHlpAssert.h
@@ -0,0 +1,369 @@
+/* $Id: kHlpAssert.h 119 2021-12-19 13:01:47Z bird $ */
+/** @file
+ * kHlpAssert - Assertion Macros.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___kHlpAssert_h___
+#define ___kHlpAssert_h___
+
+#include <k/kHlpDefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup grp_kHlpAssert - Assertion Macros
+ * @addtogroup grp_kHlp
+ * @{ */
+
+/** @def K_STRICT
+ * Assertions are enabled when K_STRICT is \#defined. */
+
+/** @def kHlpAssertBreakpoint
+ * Emits a breakpoint instruction or somehow triggers a debugger breakpoint.
+ */
+#ifdef _MSC_VER
+# define kHlpAssertBreakpoint() do { __debugbreak(); } while (0)
+#elif defined(__GNUC__) && K_OS == K_OS_SOLARIS && (K_ARCH == K_ARCH_AMD64 || K_ARCH == K_ARCH_X86_32)
+# define kHlpAssertBreakpoint() do { __asm__ __volatile__ ("int $3"); } while (0)
+#elif defined(__GNUC__) && (K_ARCH == K_ARCH_AMD64 || K_ARCH == K_ARCH_X86_32 || K_ARCH == K_ARCH_X86_16)
+# define kHlpAssertBreakpoint() do { __asm__ __volatile__ ("int3"); } while (0)
+#elif defined(__GNUC__) && (K_ARCH == K_ARCH_ARM_64 || K_ARCH == K_ARCH_ARM_32) /* probably not supported by older ARM CPUs */
+# define kHlpAssertBreakpoint() do { __asm__ __volatile__ ("brk #0x1"); } while (0)
+#elif defined(__GNUC__) && (K_ARCH == K_ARCH_SPARC_32)
+# define kHlpAssertBreakpoint() do { __asm__ __volatile__ ("unimp 0"); } while (0) /*??*/
+#elif defined(__GNUC__) && (K_ARCH == K_ARCH_SPARC_64)
+# define kHlpAssertBreakpoint() do { __asm__ __volatile__ ("illtrap 0"); } while (0) /*??*/
+#else
+# error "Port Me"
+#endif
+
+/** @def K_FUNCTION
+ * Undecorated function name macro expanded by the compiler.
+ */
+#if defined(__GNUC__)
+# define K_FUNCTION __func__
+#else
+# define K_FUNCTION __FUNCTION__
+#endif
+
+#ifdef K_STRICT
+
+# define kHlpAssert(expr) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ } \
+ } while (0)
+
+# define kHlpAssertStmt(expr, stmt) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ } \
+ } while (0)
+
+# define kHlpAssertReturn(expr, rcRet) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ return (rcRet); \
+ } \
+ } while (0)
+
+# define kHlpAssertStmtReturn(expr, stmt, rcRet) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return (rcRet); \
+ } \
+ } while (0)
+
+# define kHlpAssertReturnVoid(expr) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ return; \
+ } \
+ } while (0)
+
+# define kHlpAssertStmtReturnVoid(expr, stmt) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return; \
+ } \
+ } while (0)
+
+# define kHlpAssertMsg(expr, msg) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ } \
+ } while (0)
+
+# define kHlpAssertMsgStmt(expr, msg, stmt) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ } \
+ } while (0)
+
+# define kHlpAssertMsgReturn(expr, msg, rcRet) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ return (rcRet); \
+ } \
+ } while (0)
+
+# define kHlpAssertMsgStmtReturn(expr, msg, stmt, rcRet) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return (rcRet); \
+ } \
+ } while (0)
+
+# define kHlpAssertMsgReturnVoid(expr, msg) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ return; \
+ } \
+ } while (0)
+
+# define kHlpAssertMsgStmtReturnVoid(expr, msg, stmt) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return; \
+ } \
+ } while (0)
+
+/* Same as above, only no expression. */
+
+# define kHlpAssertFailed() \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ } while (0)
+
+# define kHlpAssertFailedStmt(stmt) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ } while (0)
+
+# define kHlpAssertFailedReturn(rcRet) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ return (rcRet); \
+ } while (0)
+
+# define kHlpAssertFailedStmtReturn(stmt, rcRet) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return (rcRet); \
+ } while (0)
+
+# define kHlpAssertFailedReturnVoid() \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ return; \
+ } while (0)
+
+# define kHlpAssertFailedStmtReturnVoid(stmt) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return; \
+ } while (0)
+
+# define kHlpAssertMsgFailed(msg) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ } while (0)
+
+# define kHlpAssertMsgFailedStmt(msg, stmt) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ } while (0)
+
+# define kHlpAssertMsgFailedReturn(msg, rcRet) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ return (rcRet); \
+ } while (0)
+
+# define kHlpAssertMsgFailedStmtReturn(msg, stmt, rcRet) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return (rcRet); \
+ } while (0)
+
+# define kHlpAssertMsgFailedReturnVoid(msg) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ return; \
+ } while (0)
+
+# define kHlpAssertMsgFailedStmtReturnVoid(msg, stmt) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return; \
+ } while (0)
+
+
+#else /* !K_STRICT */
+
+# define kHlpAssert(expr) do { } while (0)
+# define kHlpAssertStmt(expr, stmt) do { if (!(expr)) { stmt; } } while (0)
+# define kHlpAssertReturn(expr, rcRet) do { if (!(expr)) return (rcRet); } while (0)
+# define kHlpAssertStmtReturn(expr, stmt, rcRet) do { if (!(expr)) { stmt; return (rcRet); } } while (0)
+# define kHlpAssertReturnVoid(expr) do { if (!(expr)) return; } while (0)
+# define kHlpAssertStmtReturnVoid(expr, stmt) do { if (!(expr)) { stmt; return; } } while (0)
+# define kHlpAssertMsg(expr, msg) do { } while (0)
+# define kHlpAssertMsgStmt(expr, msg, stmt) do { if (!(expr)) { stmt; } } while (0)
+# define kHlpAssertMsgReturn(expr, msg, rcRet) do { if (!(expr)) return (rcRet); } while (0)
+# define kHlpAssertMsgStmtReturn(expr, msg, stmt, rcRet) do { if (!(expr)) { stmt; return (rcRet); } } while (0)
+# define kHlpAssertMsgReturnVoid(expr, msg) do { if (!(expr)) return; } while (0)
+# define kHlpAssertMsgStmtReturnVoid(expr, msg, stmt) do { if (!(expr)) { stmt; return; } } while (0)
+/* Same as above, only no expression: */
+# define kHlpAssertFailed() do { } while (0)
+# define kHlpAssertFailedStmt(stmt) do { stmt; } while (0)
+# define kHlpAssertFailedReturn(rcRet) do { return (rcRet); } while (0)
+# define kHlpAssertFailedStmtReturn(stmt, rcRet) do { stmt; return (rcRet); } while (0)
+# define kHlpAssertFailedReturnVoid() do { return; } while (0)
+# define kHlpAssertFailedStmtReturnVoid(stmt) do { stmt; return; } while (0)
+# define kHlpAssertMsgFailed(msg) do { } while (0)
+# define kHlpAssertMsgFailedStmt(msg, stmt) do { stmt; } while (0)
+# define kHlpAssertMsgFailedReturn(msg, rcRet) do { return (rcRet); } while (0)
+# define kHlpAssertMsgFailedStmtReturn(msg, stmt, rcRet) do { { stmt; return (rcRet); } } while (0)
+# define kHlpAssertMsgFailedReturnVoid(msg) do { return; } while (0)
+# define kHlpAssertMsgFailedStmtReturnVoid(msg, stmt) do { stmt; return; } while (0)
+
+#endif /* !K_STRICT */
+
+#define kHlpAssertPtr(ptr) kHlpAssertMsg(K_VALID_PTR(ptr), ("%s = %p\n", #ptr, (ptr)))
+#define kHlpAssertPtrReturn(ptr, rcRet) kHlpAssertMsgReturn(K_VALID_PTR(ptr), ("%s = %p -> %d\n", #ptr, (ptr), (rcRet)), (rcRet))
+#define kHlpAssertPtrReturn(ptr, rcRet) kHlpAssertMsgReturn(K_VALID_PTR(ptr), ("%s = %p -> %d\n", #ptr, (ptr), (rcRet)), (rcRet))
+#define kHlpAssertPtrReturnVoid(ptr) kHlpAssertMsgReturnVoid(K_VALID_PTR(ptr), ("%s = %p -> %d\n", #ptr, (ptr), (rcRet)))
+#define kHlpAssertPtrNull(ptr) kHlpAssertMsg(!(ptr) || K_VALID_PTR(ptr), ("%s = %p\n", #ptr, (ptr)))
+#define kHlpAssertPtrNullReturn(ptr, rcRet) kHlpAssertMsgReturn(!(ptr) || K_VALID_PTR(ptr), ("%s = %p -> %d\n", #ptr, (ptr), (rcRet)), (rcRet))
+#define kHlpAssertPtrNullReturnVoid(ptr) kHlpAssertMsgReturnVoid(!(ptr) || K_VALID_PTR(ptr), ("%s = %p -> %d\n", #ptr, (ptr), (rcRet)))
+#define kHlpAssertRC(rc) kHlpAssertMsg((rc) == 0, ("%s = %d\n", #rc, (rc)))
+#define kHlpAssertRCReturn(rc, rcRet) kHlpAssertMsgReturn((rc) == 0, ("%s = %d -> %d\n", #rc, (rc), (rcRet)), (rcRet))
+#define kHlpAssertRCReturnVoid(rc) kHlpAssertMsgReturnVoid((rc) == 0, ("%s = %d -> %d\n", #rc, (rc), (rcRet)))
+
+
+/**
+ * Helper function that displays the first part of the assertion message.
+ *
+ * @param pszExpr The expression.
+ * @param pszFile The file name.
+ * @param iLine The line number is the file.
+ * @param pszFunction The function name.
+ * @internal
+ */
+KHLP_DECL(void) kHlpAssertMsg1(const char *pszExpr, const char *pszFile, unsigned iLine, const char *pszFunction);
+
+/**
+ * Helper function that displays custom assert message.
+ *
+ * @param pszFormat Format string that get passed to vprintf.
+ * @param ... Format arguments.
+ * @internal
+ */
+KHLP_DECL(void) kHlpAssertMsg2(const char *pszFormat, ...);
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/lib/kStuff/include/k/kHlpDefs.h b/src/lib/kStuff/include/k/kHlpDefs.h
new file mode 100644
index 0000000..bcda10a
--- /dev/null
+++ b/src/lib/kStuff/include/k/kHlpDefs.h
@@ -0,0 +1,55 @@
+/* $Id: kHlpDefs.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kHlpDefs - Helper Definitions.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kHlpDefs_h___
+#define ___k_kHlpDefs_h___
+
+#include <k/kDefs.h>
+
+/** @defgroup grp_kHlpDefs - Definitions
+ * @addtogroup grp_kHlp
+ * @{ */
+
+/** @def KHLP_DECL
+ * Declares a kHlp function according to build context.
+ * @param type The return type.
+ */
+#if defined(KHLP_BUILDING_DYNAMIC)
+# define KHLP_DECL(type) K_DECL_EXPORT(type)
+#elif defined(KHLP_BUILT_DYNAMIC)
+# define KHLP_DECL(type) K_DECL_IMPORT(type)
+#else
+# define KHLP_DECL(type) type
+#endif
+
+/** @} */
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kHlpEnv.h b/src/lib/kStuff/include/k/kHlpEnv.h
new file mode 100644
index 0000000..95c2bda
--- /dev/null
+++ b/src/lib/kStuff/include/k/kHlpEnv.h
@@ -0,0 +1,55 @@
+/* $Id: kHlpEnv.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kHlpEnv - 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.
+ */
+
+#ifndef ___k_kHlpEnv_h___
+#define ___k_kHlpEnv_h___
+
+#include <k/kHlpDefs.h>
+#include <k/kTypes.h>
+
+/** @defgroup grp_kHlpEnv kHlpEnv - Environment Manipulation
+ * @addtogroup grp_kHlp
+ * @{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+KHLP_DECL(int) kHlpGetEnv(const char *pszVar, char *pszVal, KSIZE cchVal);
+KHLP_DECL(int) kHlpGetEnvUZ(const char *pszVar, KSIZE *pcb);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kHlpPath.h b/src/lib/kStuff/include/k/kHlpPath.h
new file mode 100644
index 0000000..c9d6ce5
--- /dev/null
+++ b/src/lib/kStuff/include/k/kHlpPath.h
@@ -0,0 +1,57 @@
+/* $Id: kHlpPath.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kHlpPath - Path 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.
+ */
+
+#ifndef ___k_kHlpPath_h___
+#define ___k_kHlpPath_h___
+
+#include <k/kHlpDefs.h>
+#include <k/kTypes.h>
+
+/** @defgroup grp_kHlpPath kHlpPath - Path Manipulation
+ * @addtogroup grp_kHlp
+ * @{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+KHLP_DECL(char *) kHlpGetFilename(const char *pszFilename);
+KHLP_DECL(char *) kHlpGetSuff(const char *pszFilename);
+KHLP_DECL(char *) kHlpGetExt(const char *pszFilename);
+KHLP_DECL(int) kHlpIsFilenameOnly(const char *pszFilename);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kHlpProcess.h b/src/lib/kStuff/include/k/kHlpProcess.h
new file mode 100644
index 0000000..c637545
--- /dev/null
+++ b/src/lib/kStuff/include/k/kHlpProcess.h
@@ -0,0 +1,54 @@
+/* $Id: kHlpProcess.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kHlpProcess - 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.
+ */
+
+#ifndef ___k_kHlpProcess_h___
+#define ___k_kHlpProcess_h___
+
+#include <k/kHlpDefs.h>
+#include <k/kTypes.h>
+
+/** @defgroup grp_kHlpProcess kHlpProcess - Process Management
+ * @addtogroup grp_kHlp
+ * @{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+KHLP_DECL(void) kHlpExit(int rc);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kHlpSem.h b/src/lib/kStuff/include/k/kHlpSem.h
new file mode 100644
index 0000000..72c6407
--- /dev/null
+++ b/src/lib/kStuff/include/k/kHlpSem.h
@@ -0,0 +1,54 @@
+/* $Id: kHlpSem.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kHlpSem - Semaphores.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kHlpSem_h___
+#define ___k_kHlpSem_h___
+
+#include <k/kHlpDefs.h>
+#include <k/kTypes.h>
+
+/** @defgroup grp_kHlpSem kHlpSem - Semaphore
+ * @addtogroup grp_kHlp
+ * @{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif
+
+
diff --git a/src/lib/kStuff/include/k/kHlpString.h b/src/lib/kStuff/include/k/kHlpString.h
new file mode 100644
index 0000000..23da03d
--- /dev/null
+++ b/src/lib/kStuff/include/k/kHlpString.h
@@ -0,0 +1,156 @@
+/* $Id: kHlpString.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kHlpString - String And Memory Routines.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kHlpString_h___
+#define ___k_kHlpString_h___
+
+#include <k/kHlpDefs.h>
+#include <k/kTypes.h>
+
+#if 0 /* optimize / fix this later */
+#ifdef __GNUC__
+/** memchr */
+# define kHlpMemChr(a,b,c) __builtin_memchr(a,b,c)
+/** memcmp */
+# define kHlpMemComp(a,b,c) __builtin_memcmp(a,b,c)
+/** memcpy */
+# define kHlpMemCopy(a,b,c) __builtin_memcpy(a,b,c)
+/** memset */
+# define kHlpMemSet(a,b,c) __builtin_memset(a,b,c)
+/** strchr */
+# define kHlpStrChr(a, b) __builtin_strchr(a, b)
+/** strcmp */
+# define kHlpStrComp(a, b) __builtin_strcmp(a, b)
+/** strncmp */
+# define kHlpStrNComp(a,b,c) __builtin_strncmp(a, b, c)
+/** strlen */
+# define kHlpStrLen(a) __builtin_strlen(a)
+
+#elif defined(_MSC_VER)
+# pragma intrinsic(memcmp, memcpy, memset, strcmp, strlen)
+/** memcmp */
+# define kHlpMemComp(a,b,c) memcmp(a,b,c)
+/** memcpy */
+# define kHlpMemCopy(a,b,c) memcpy(a,b,c)
+/** memset */
+# define kHlpMemSet(a,b,c) memset(a,b,c)
+/** strcmp */
+# define kHlpStrComp(a, b) strcmp(a, b)
+/** strlen */
+# define kHlpStrLen(a) strlen(a)
+#else
+# error "Port Me"
+#endif
+#endif /* disabled */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef kHlpMemChr
+KHLP_DECL(void *) kHlpMemChr(const void *pv, int ch, KSIZE cb);
+#endif
+#ifndef kHlpMemComp
+KHLP_DECL(int) kHlpMemComp(const void *pv1, const void *pv2, KSIZE cb);
+#endif
+#ifndef kHlpMemComp
+KHLP_DECL(void *) kHlpMemPComp(const void *pv1, const void *pv2, KSIZE cb);
+#endif
+#ifndef kHlpMemCopy
+KHLP_DECL(void *) kHlpMemCopy(void *pv1, const void *pv2, KSIZE cb);
+#endif
+#ifndef kHlpMemPCopy
+KHLP_DECL(void *) kHlpMemPCopy(void *pv1, const void *pv2, KSIZE cb);
+#endif
+#ifndef kHlpMemMove
+KHLP_DECL(void *) kHlpMemMove(void *pv1, const void *pv2, KSIZE cb);
+#endif
+#ifndef kHlpMemPMove
+KHLP_DECL(void *) kHlpMemPMove(void *pv1, const void *pv2, KSIZE cb);
+#endif
+#ifndef kHlpMemSet
+KHLP_DECL(void *) kHlpMemSet(void *pv1, int ch, KSIZE cb);
+#endif
+#ifndef kHlpMemPSet
+KHLP_DECL(void *) kHlpMemPSet(void *pv1, int ch, KSIZE cb);
+#endif
+KHLP_DECL(int) kHlpMemICompAscii(const void *pv1, const void *pv2, KSIZE cb);
+
+#ifndef kHlpStrCat
+KHLP_DECL(char *) kHlpStrCat(char *psz1, const char *psz2);
+#endif
+#ifndef kHlpStrPCat
+KHLP_DECL(char *) kHlpStrPCat(char *psz1, const char *psz2);
+#endif
+#ifndef kHlpStrNCat
+KHLP_DECL(char *) kHlpStrNCat(char *psz1, const char *psz2, KSIZE cb);
+#endif
+#ifndef kHlpStrPNCat
+KHLP_DECL(char *) kHlpStrNPCat(char *psz1, const char *psz2, KSIZE cb);
+#endif
+#ifndef kHlpStrChr
+KHLP_DECL(char *) kHlpStrChr(const char *psz, int ch);
+#endif
+#ifndef kHlpStrRChr
+KHLP_DECL(char *) kHlpStrRChr(const char *psz, int ch);
+#endif
+#ifndef kHlpStrComp
+KHLP_DECL(int) kHlpStrComp(const char *psz1, const char *psz2);
+#endif
+KHLP_DECL(char *) kHlpStrPComp(const char *psz1, const char *psz2);
+#ifndef kHlpStrNComp
+KHLP_DECL(int) kHlpStrNComp(const char *psz1, const char *psz2, KSIZE cch);
+#endif
+KHLP_DECL(char *) kHlpStrNPComp(const char *psz1, const char *psz2, KSIZE cch);
+KHLP_DECL(int) kHlpStrICompAscii(const char *pv1, const char *pv2);
+KHLP_DECL(char *) kHlpStrIPCompAscii(const char *pv1, const char *pv2);
+KHLP_DECL(int) kHlpStrNICompAscii(const char *pv1, const char *pv2, KSIZE cch);
+KHLP_DECL(char *) kHlpStrNIPCompAscii(const char *pv1, const char *pv2, KSIZE cch);
+#ifndef kHlpStrCopy
+KHLP_DECL(char *) kHlpStrCopy(char *psz1, const char *psz2);
+#endif
+#ifndef kHlpStrPCopy
+KHLP_DECL(char *) kHlpStrPCopy(char *psz1, const char *psz2);
+#endif
+#ifndef kHlpStrLen
+KHLP_DECL(KSIZE) kHlpStrLen(const char *psz1);
+#endif
+#ifndef kHlpStrNLen
+KHLP_DECL(KSIZE) kHlpStrNLen(const char *psz, KSIZE cchMax);
+#endif
+
+KHLP_DECL(char *) kHlpInt2Ascii(char *psz, KSIZE cch, long lVal, unsigned iBase);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kHlpSys.h b/src/lib/kStuff/include/k/kHlpSys.h
new file mode 100644
index 0000000..63aeaee
--- /dev/null
+++ b/src/lib/kStuff/include/k/kHlpSys.h
@@ -0,0 +1,79 @@
+/* $Id: kHlpSys.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kHlpSys - System Call Prototypes.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kHlpSys_h___
+#define ___k_kHlpSys_h___
+
+#include <k/kHlpDefs.h>
+#include <k/kTypes.h>
+
+/** @defgroup grp_kHlpSys kHlpSys - System Call Prototypes
+ * @addtogroup grp_kHlp
+ * @{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* common unix stuff. */
+#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
+KSSIZE kHlpSys_readlink(const char *pszPath, char *pszBuf, KSIZE cbBuf);
+int kHlpSys_open(const char *filename, int flags, int mode);
+int kHlpSys_close(int fd);
+KFOFF kHlpSys_lseek(int fd, int whench, KFOFF off);
+KSSIZE kHlpSys_read(int fd, void *pvBuf, KSIZE cbBuf);
+KSSIZE kHlpSys_write(int fd, const void *pvBuf, KSIZE cbBuf);
+void *kHlpSys_mmap(void *addr, KSIZE len, int prot, int flags, int fd, KI64 off);
+int kHlpSys_mprotect(void *addr, KSIZE len, int prot);
+int kHlpSys_munmap(void *addr, KSIZE len);
+void kHlpSys_exit(int rc);
+#endif
+
+/* specific */
+#if K_OS == K_OS_DARWIN
+
+#elif K_OS == K_OS_LINUX
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif
+
+
diff --git a/src/lib/kStuff/include/k/kHlpThread.h b/src/lib/kStuff/include/k/kHlpThread.h
new file mode 100644
index 0000000..1b2f233
--- /dev/null
+++ b/src/lib/kStuff/include/k/kHlpThread.h
@@ -0,0 +1,55 @@
+/* $Id: kHlpThread.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kHlpThread - 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.
+ */
+
+#ifndef ___k_kHlpThread_h___
+#define ___k_kHlpThread_h___
+
+#include <k/kHlpDefs.h>
+#include <k/kTypes.h>
+
+/** @defgroup grp_kHlpThread kHlpThread - Thread Management
+ * @addtogroup grp_kHlp
+ * @{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+KHLP_DECL(void) kHlpSleep(unsigned cMillies);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif
+
+
diff --git a/src/lib/kStuff/include/k/kLdr.h b/src/lib/kStuff/include/k/kLdr.h
new file mode 100644
index 0000000..4aefb66
--- /dev/null
+++ b/src/lib/kStuff/include/k/kLdr.h
@@ -0,0 +1,959 @@
+/* $Id: kLdr.h 117 2020-03-15 15:23:36Z bird $ */
+/** @file
+ * kLdr - The Dynamic Loader.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kLdr_h___
+#define ___k_kLdr_h___
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Include the base typedefs and macros.
+ */
+#include <k/kDefs.h>
+#include <k/kTypes.h>
+#include <k/kCpus.h>
+
+
+/** @defgroup grp_kLdrBasic kLdr Basic Types
+ * @{ */
+
+/** The kLdr address type. */
+typedef KU64 KLDRADDR;
+/** Pointer to a kLdr address. */
+typedef KLDRADDR *PKLDRADDR;
+/** Pointer to a const kLdr address. */
+typedef const KLDRADDR *PCKLDRADDR;
+
+/** NIL address. */
+#define NIL_KLDRADDR (~(KU64)0)
+
+/** @def PRI_KLDRADDR
+ * printf format type. */
+#ifdef _MSC_VER
+# define PRI_KLDRADDR "I64x"
+#else
+# define PRI_KLDRADDR "llx"
+#endif
+
+/** Align a KSIZE value. */
+#define KLDR_ALIGN_ADDR(val, align) ( ((val) + ((align) - 1)) & ~(KLDRADDR)((align) - 1) )
+
+
+/** The kLdr size type. */
+typedef KU64 KLDRSIZE;
+/** Pointer to a kLdr size. */
+typedef KLDRSIZE *PKLDRSIZE;
+/** Pointer to a const kLdr size. */
+typedef const KLDRSIZE *PCKLDRSIZE;
+
+/** @def PRI_KLDRSIZE
+ * printf format type. */
+#ifdef _MSC_VER
+# define PRI_KLDRSIZE "I64x"
+#else
+# define PRI_KLDRSIZE "llx"
+#endif
+
+
+/** The kLdr file offset type. */
+typedef long KLDRFOFF;
+/** Pointer to a kLdr file offset type. */
+typedef KLDRFOFF *PKLDRFOFF;
+/** Pointer to a const kLdr file offset type. */
+typedef const KLDRFOFF *PCKLDRFOFF;
+
+/** @def PRI_KLDRFOFF
+ * printf format type. */
+#define PRI_KLDRFOFF "lx"
+
+
+/**
+ * Union of all the integer types.
+ */
+typedef union KLDRU
+{
+ KI8 i8; /**< KI8 view. */
+ KU8 u8; /**< KU8 view. */
+ KI16 i16; /**< KI16 view. */
+ KU16 u16; /**< KU16 view. */
+ KI32 i32; /**< KI32 view. */
+ KU32 u32; /**< KU32 view. */
+ KI64 i64; /**< KI64 view. */
+ KU64 u64; /**< KU64 view. */
+
+ KI8 ai8[8]; /**< KI8 array view . */
+ KU8 au8[8]; /**< KU8 array view. */
+ KI16 ai16[4];/**< KI16 array view . */
+ KU16 au16[4];/**< KU16 array view. */
+ KI32 ai32[2];/**< KI32 array view . */
+ KU32 au32[2];/**< KU32 array view. */
+
+ signed char ch; /**< signed char view. */
+ unsigned char uch; /**< unsigned char view. */
+ signed short s; /**< signed short view. */
+ unsigned short us; /**< unsigned short view. */
+ signed int i; /**< signed int view. */
+ unsigned int u; /**< unsigned int view. */
+ signed long l; /**< signed long view. */
+ unsigned long ul; /**< unsigned long view. */
+ void *pv; /**< void pointer view. */
+
+ KLDRADDR Addr; /**< kLdr address view. */
+ KLDRSIZE Size; /**< kLdr size view. */
+} KLDRU;
+/** Pointer to an integer union. */
+typedef KLDRU *PKLDRU;
+/** Pointer to a const integer union. */
+typedef const KLDRU *PCKLDRU;
+
+
+/**
+ * Union of pointers to all the integer types.
+ */
+typedef union KLDRPU
+{
+ KI8 *pi8; /**< KI8 view. */
+ KU8 *pu8; /**< KU8 view. */
+ KI16 *pi16; /**< KI16 view. */
+ KU16 *pu16; /**< KU16 view. */
+ KI32 *pi32; /**< KI32 view. */
+ KU32 *pu32; /**< KU32 view. */
+ KI64 *pi64; /**< KI64 view. */
+ KU64 *pu64; /**< KU64 view. */
+
+ signed char *pch; /**< signed char view. */
+ unsigned char *puch; /**< unsigned char view. */
+ signed short *ps; /**< signed short view. */
+ unsigned short *pus; /**< unsigned short view. */
+ signed int *pi; /**< signed int view. */
+ unsigned int *pu; /**< unsigned int view. */
+ signed long *pl; /**< signed long view. */
+ unsigned long *pul; /**< unsigned long view. */
+ void *pv; /**< void pointer view. */
+} KLDRPU;
+/** Pointer to an integer pointer union. */
+typedef KLDRPU *PKLDRPU;
+/** Pointer to a const integer pointer union. */
+typedef const KLDRPU *PCKLDRPU;
+
+/** @} */
+
+
+/** @defgroup grp_kLdrMod kLdrMod - The executable image intepreter
+ * @{ */
+
+/**
+ * Debug info type (from the loader point of view).
+ */
+typedef enum KLDRDBGINFOTYPE
+{
+ /** The usual invalid enum value. */
+ KLDRDBGINFOTYPE_INVALID = 0,
+ /** Unknown debug info format. */
+ KLDRDBGINFOTYPE_UNKNOWN,
+ /** Stabs. */
+ KLDRDBGINFOTYPE_STABS,
+ /** Debug With Arbitrary Record Format (DWARF). */
+ KLDRDBGINFOTYPE_DWARF,
+ /** Microsoft Codeview debug info. */
+ KLDRDBGINFOTYPE_CODEVIEW,
+ /** Watcom debug info. */
+ KLDRDBGINFOTYPE_WATCOM,
+ /** IBM High Level Language debug info.. */
+ KLDRDBGINFOTYPE_HLL,
+ /** The end of the valid debug info values (exclusive). */
+ KLDRDBGINFOTYPE_END,
+ /** Blow the type up to 32-bit. */
+ KLDRDBGINFOTYPE_32BIT_HACK = 0x7fffffff
+} KLDRDBGINFOTYPE;
+/** Pointer to a kLdr debug info type. */
+typedef KLDRDBGINFOTYPE *PKLDRDBGINFOTYPE;
+
+
+/**
+ * Stack information.
+ */
+typedef struct KLDRSTACKINFO
+{
+ /** The base address of the stack (sub) segment.
+ * Set this to NIL_KLDRADDR if the module doesn't include any stack segment. */
+ KLDRADDR Address;
+ /** The base address of the stack (sub) segment, link address.
+ * Set this to NIL_KLDRADDR if the module doesn't include any stack (sub)segment. */
+ KLDRADDR LinkAddress;
+ /** The stack size of the main thread.
+ * If no stack (sub)segment in the module, this is the stack size of the main thread.
+ * If the module doesn't contain this kind of information this field will be set to 0. */
+ KLDRSIZE cbStack;
+ /** The stack size of non-main threads.
+ * If the module doesn't contain this kind of information this field will be set to 0. */
+ KLDRSIZE cbStackThread;
+} KLDRSTACKINFO;
+/** Pointer to stack information. */
+typedef KLDRSTACKINFO *PKLDRSTACKINFO;
+/** Pointer to const stack information. */
+typedef const KLDRSTACKINFO *PCKLDRSTACKINFO;
+
+
+/**
+ * Loader segment.
+ */
+typedef struct KLDRSEG
+{
+ /** Variable free to use for the kLdr user. */
+ void *pvUser;
+ /** The segment name. (Might not be zero terminated!) */
+ const char *pchName;
+ /** The length of the segment name. */
+ KU32 cchName;
+ /** The flat selector to use for the segment (i.e. data/code).
+ * Primarily a way for the user to specify selectors for the LX/LE and NE interpreters. */
+ KU16 SelFlat;
+ /** The 16-bit selector to use for the segment.
+ * Primarily a way for the user to specify selectors for the LX/LE and NE interpreters. */
+ KU16 Sel16bit;
+ /** Segment flags. */
+ KU32 fFlags;
+ /** The segment protection. */
+ KPROT enmProt;
+ /** The size of the segment. */
+ KLDRSIZE cb;
+ /** The required segment alignment.
+ * The to 0 if the segment isn't supposed to be mapped. */
+ KLDRADDR Alignment;
+ /** The link address.
+ * Set to NIL_KLDRADDR if the segment isn't supposed to be
+ * mapped or if the image doesn't have link addresses. */
+ KLDRADDR LinkAddress;
+ /** File offset of the segment.
+ * Set to -1 if no file backing (like BSS). */
+ KLDRFOFF offFile;
+ /** Size of the file bits of the segment.
+ * Set to -1 if no file backing (like BSS). */
+ KLDRFOFF cbFile;
+ /** The relative virtual address when mapped.
+ * Set to NIL_KLDRADDR if the segment isn't supposed to be mapped. */
+ KLDRADDR RVA;
+ /** The size of the segment including the alignment gap up to the next segment when mapped. */
+ KSIZE cbMapped;
+ /** The address the segment was mapped at by kLdrModMap().
+ * Set to 0 if not mapped. */
+ KUPTR MapAddress;
+} KLDRSEG;
+
+
+/** @name Segment flags
+ * @{ */
+/** The segment is 16-bit. When not set the default of the target architecture is assumed. */
+#define KLDRSEG_FLAG_16BIT 1
+/** The segment requires a 16-bit selector alias. (OS/2) */
+#define KLDRSEG_FLAG_OS2_ALIAS16 2
+/** Conforming segment (x86 weirdness). (OS/2) */
+#define KLDRSEG_FLAG_OS2_CONFORM 4
+/** IOPL (ring-2) segment. (OS/2) */
+#define KLDRSEG_FLAG_OS2_IOPL 8
+/** @} */
+
+
+/**
+ * Loader module format.
+ */
+typedef enum KLDRFMT
+{
+ /** The usual invalid 0 format. */
+ KLDRFMT_INVALID = 0,
+ /** The native OS loader. */
+ KLDRFMT_NATIVE,
+ /** The AOUT loader. */
+ KLDRFMT_AOUT,
+ /** The ELF loader. */
+ KLDRFMT_ELF,
+ /** The LX loader. */
+ KLDRFMT_LX,
+ /** The Mach-O loader. */
+ KLDRFMT_MACHO,
+ /** The PE loader. */
+ KLDRFMT_PE,
+ /** The end of the valid format values (exclusive). */
+ KLDRFMT_END,
+ /** Hack to blow the type up to 32-bit. */
+ KLDRFMT_32BIT_HACK = 0x7fffffff
+} KLDRFMT;
+
+
+/**
+ * Loader module type.
+ */
+typedef enum KLDRTYPE
+{
+ /** The usual invalid 0 type. */
+ KLDRTYPE_INVALID = 0,
+ /** Object file. */
+ KLDRTYPE_OBJECT,
+ /** Executable module, fixed load address. */
+ KLDRTYPE_EXECUTABLE_FIXED,
+ /** Executable module, relocatable, non-fixed load address. */
+ KLDRTYPE_EXECUTABLE_RELOCATABLE,
+ /** Executable module, position independent code, non-fixed load address. */
+ KLDRTYPE_EXECUTABLE_PIC,
+ /** Shared library, fixed load address.
+ * Typically a system library. */
+ KLDRTYPE_SHARED_LIBRARY_FIXED,
+ /** Shared library, relocatable, non-fixed load address. */
+ KLDRTYPE_SHARED_LIBRARY_RELOCATABLE,
+ /** Shared library, position independent code, non-fixed load address. */
+ KLDRTYPE_SHARED_LIBRARY_PIC,
+ /** DLL that contains no code or data only imports and exports. (Chiefly OS/2.) */
+ KLDRTYPE_FORWARDER_DLL,
+ /** Core or dump. */
+ KLDRTYPE_CORE,
+ /** Debug module (debug info with empty code & data segments). */
+ KLDRTYPE_DEBUG_INFO,
+ /** The end of the valid types values (exclusive). */
+ KLDRTYPE_END,
+ /** Hack to blow the type up to 32-bit. */
+ KLDRTYPE_32BIT_HACK = 0x7fffffff
+} KLDRTYPE;
+
+
+/**
+ * Loader endian indicator.
+ */
+typedef enum KLDRENDIAN
+{
+ /** The usual invalid endian. */
+ KLDRENDIAN_INVALID,
+ /** Little endian. */
+ KLDRENDIAN_LITTLE,
+ /** Bit endian. */
+ KLDRENDIAN_BIG,
+ /** Endianness doesn't have a meaning in the context. */
+ KLDRENDIAN_NA,
+ /** The end of the valid endian values (exclusive). */
+ KLDRENDIAN_END,
+ /** Hack to blow the type up to 32-bit. */
+ KLDRENDIAN_32BIT_HACK = 0x7fffffff
+} KLDRENDIAN;
+
+
+/** @name KLDRMOD::fFlags
+ * @{ */
+/** The link address doesn't form a contiguous image, from the first to the
+ * last segment. */
+#define KLDRMOD_FLAGS_NON_CONTIGUOUS_LINK_ADDRS K_BIT32(0)
+/** @} */
+
+/** Pointer to a module interpreter method table. */
+typedef struct KLDRMODOPS *PKLDRMODOPS;
+/** Pointer to const module interpreter methods table. */
+typedef const struct KLDRMODOPS *PCKLDRMODOPS;
+
+/**
+ * Module interpreter instance.
+ * All members are read only unless you're kLdrMod or the module interpreter.
+ */
+typedef struct KLDRMOD
+{
+ /** Magic number (KLDRMOD_MAGIC). */
+ KU32 u32Magic;
+ /** The format of this module. */
+ KLDRFMT enmFmt;
+ /** The type of module. */
+ KLDRTYPE enmType;
+ /** The CPU architecture this module was built for. */
+ KCPUARCH enmArch;
+ /** The minium cpu this module was built for.
+ * This might not be accurate, so use kLdrModCanExecuteOn() to check. */
+ KCPU enmCpu;
+ /** The endian used by the module. */
+ KLDRENDIAN enmEndian;
+ /** Module open flags, KLDRMOD_OPEN_FLAGS_XXX. */
+ KU32 fFlags;
+ /** The filename length (bytes). */
+ KU32 cchFilename;
+ /** The filename. */
+ const char *pszFilename;
+ /** The module name. */
+ const char *pszName;
+ /** The module name length (bytes). */
+ KU32 cchName;
+ /** The number of segments in the module. */
+ KU32 cSegments;
+ /** Pointer to the loader methods.
+ * Not meant for calling directly thru! */
+ PCKLDRMODOPS pOps;
+ /** Pointer to the read instance. (Can be NULL after kLdrModDone().)*/
+ PKRDR pRdr;
+ /** The module data. */
+ void *pvData;
+ /** Segments. (variable size, can be zero) */
+ KLDRSEG aSegments[1];
+} KLDRMOD, *PKLDRMOD, **PPKLDRMOD;
+
+/** The magic for KLDRMOD::u32Magic. (Kosuke Fujishima) */
+#define KLDRMOD_MAGIC 0x19640707
+
+
+/** Special base address value alias for the link address. */
+#define KLDRMOD_BASEADDRESS_LINK (~(KLDRADDR)1)
+/** Special base address value alias for the actual load address (must be mapped). */
+#define KLDRMOD_BASEADDRESS_MAP (~(KLDRADDR)2)
+
+/** Special import module ordinal value used to indicate that there is no
+ * specific module associated with the requested symbol. */
+#define NIL_KLDRMOD_IMPORT (~(KU32)0)
+
+/** Special symbol ordinal value used to indicate that the symbol
+ * only has a string name. */
+#define NIL_KLDRMOD_SYM_ORDINAL (~(KU32)0)
+
+
+/** @name Load symbol kind flags.
+ * @{ */
+/** The bitness doesn't matter. */
+#define KLDRSYMKIND_NO_BIT 0x00000000
+/** 16-bit symbol. */
+#define KLDRSYMKIND_16BIT 0x00000001
+/** 32-bit symbol. */
+#define KLDRSYMKIND_32BIT 0x00000002
+/** 64-bit symbol. */
+#define KLDRSYMKIND_64BIT 0x00000003
+/** Mask out the bit.*/
+#define KLDRSYMKIND_BIT_MASK 0x00000003
+/** We don't know the type of symbol. */
+#define KLDRSYMKIND_NO_TYPE 0x00000000
+/** The symbol is a code object (method/function/procedure/whateveryouwannacallit). */
+#define KLDRSYMKIND_CODE 0x00000010
+/** The symbol is a data object. */
+#define KLDRSYMKIND_DATA 0x00000020
+/** Mask out the symbol type. */
+#define KLDRSYMKIND_TYPE_MASK 0x00000030
+/** Valid symbol kind mask. */
+#define KLDRSYMKIND_MASK 0x00000033
+/** Weak symbol. */
+#define KLDRSYMKIND_WEAK 0x00000100
+/** Forwarder symbol. */
+#define KLDRSYMKIND_FORWARDER 0x00000200
+/** Request a flat symbol address. */
+#define KLDRSYMKIND_REQ_FLAT 0x00000000
+/** Request a segmented symbol address. */
+#define KLDRSYMKIND_REQ_SEGMENTED 0x40000000
+/** Request type mask. */
+#define KLDRSYMKIND_REQ_TYPE_MASK 0x40000000
+/** @} */
+
+/** @name kLdrModEnumSymbols flags.
+ * @{ */
+/** Returns ALL kinds of symbols. The default is to only return public/exported symbols. */
+#define KLDRMOD_ENUM_SYMS_FLAGS_ALL 0x00000001
+/** @} */
+
+
+/**
+ * Callback for resolving imported symbols when applying fixups.
+ *
+ * @returns 0 on success and *pValue and *pfKind filled.
+ * @returns Non-zero OS specific or kLdr status code on failure.
+ *
+ * @param pMod The module which fixups are begin applied.
+ * @param iImport The import module ordinal number or NIL_KLDRMOD_IMPORT.
+ * @param iSymbol The symbol ordinal number or NIL_KLDRMOD_SYM_ORDINAL.
+ * @param pchSymbol The symbol name. Can be NULL if iSymbol isn't nil. Doesn't have to be null-terminated.
+ * @param cchSymbol The length of the symbol.
+ * @param pszVersion The symbol version. NULL if not versioned.
+ * @param puValue Where to store the symbol value.
+ * @param pfKind Where to store the symbol kind flags.
+ * @param pvUser The user parameter specified to the relocation function.
+ */
+typedef int FNKLDRMODGETIMPORT(PKLDRMOD pMod, KU32 iImport, KU32 iSymbol, const char *pchSymbol, KSIZE cchSymbol,
+ const char *pszVersion, PKLDRADDR puValue, KU32 *pfKind, void *pvUser);
+/** Pointer to a import callback. */
+typedef FNKLDRMODGETIMPORT *PFNKLDRMODGETIMPORT;
+
+/**
+ * Symbol enumerator callback.
+ *
+ * @returns 0 if enumeration should continue.
+ * @returns non-zero if the enumeration should stop. This status code will then be returned by kLdrModEnumSymbols().
+ *
+ * @param pMod The module which symbols are being enumerated.s
+ * @param iSymbol The symbol ordinal number or NIL_KLDRMOD_SYM_ORDINAL.
+ * @param pchSymbol The symbol name. This can be NULL if there is a symbol ordinal.
+ * This can also be an empty string if the symbol doesn't have a name
+ * or it's name has been stripped.
+ * Important, this doesn't have to be a null-terminated string.
+ * @param cchSymbol The length of the symbol.
+ * @param pszVersion The symbol version. NULL if not versioned.
+ * @param uValue The symbol value.
+ * @param fKind The symbol kind flags.
+ * @param pvUser The user parameter specified to kLdrModEnumSymbols().
+ */
+typedef int FNKLDRMODENUMSYMS(PKLDRMOD pMod, KU32 iSymbol, const char *pchSymbol, KSIZE cchSymbol, const char *pszVersion,
+ KLDRADDR uValue, KU32 fKind, void *pvUser);
+/** Pointer to a symbol enumerator callback. */
+typedef FNKLDRMODENUMSYMS *PFNKLDRMODENUMSYMS;
+
+/**
+ * Debug info enumerator callback.
+ *
+ * @returns 0 to continue the enumeration.
+ * @returns non-zero if the enumeration should stop. This status code will then be returned by kLdrModEnumDbgInfo().
+ *
+ * @param pMod The module.
+ * @param iDbgInfo The debug info ordinal number / id.
+ * @param enmType The debug info type.
+ * @param iMajorVer The major version number of the debug info format. -1 if unknow - implies invalid iMinorVer.
+ * @param iMinorVer The minor version number of the debug info format. -1 when iMajorVer is -1.
+ * @param pszPartNm The name of the debug info part, NULL if not applicable.
+ * @param offFile The file offset *if* this type has one specific location in the executable image file.
+ * This is -1 if there isn't any specific file location.
+ * @param LinkAddress The link address of the debug info if it's loadable. NIL_KLDRADDR if not loadable.
+ * @param cb The size of the debug information. -1 is used if this isn't applicable.
+ * @param pszExtFile This points to the name of an external file containing the debug info.
+ * This is NULL if there isn't any external file.
+ * @param pvUser The user parameter specified to kLdrModEnumDbgInfo.
+ */
+typedef int FNKLDRENUMDBG(PKLDRMOD pMod, KU32 iDbgInfo, KLDRDBGINFOTYPE enmType, KI16 iMajorVer, KI16 iMinorVer,
+ const char *pszPartNm, KLDRFOFF offFile, KLDRADDR LinkAddress, KLDRSIZE cb,
+ const char *pszExtFile, void *pvUser);
+/** Pointer to a debug info enumerator callback. */
+typedef FNKLDRENUMDBG *PFNKLDRENUMDBG;
+
+/**
+ * Resource enumerator callback.
+ *
+ * @returns 0 to continue the enumeration.
+ * @returns non-zero if the enumeration should stop. This status code will then be returned by kLdrModEnumResources().
+ *
+ * @param pMod The module.
+ * @param idType The resource type id. NIL_KLDRMOD_RSRC_TYPE_ID if no type id.
+ * @param pszType The resource type name. NULL if no type name.
+ * @param idName The resource id. NIL_KLDRMOD_RSRC_NAME_ID if no id.
+ * @param pszName The resource name. NULL if no name.
+ * @param idLang The language id.
+ * @param AddrRsrc The address value for the resource.
+ * @param cbRsrc The size of the resource.
+ * @param pvUser The user parameter specified to kLdrModEnumDbgInfo.
+ */
+typedef int FNKLDRENUMRSRC(PKLDRMOD pMod, KU32 idType, const char *pszType, KU32 idName, const char *pszName,
+ KU32 idLang, KLDRADDR AddrRsrc, KLDRSIZE cbRsrc, void *pvUser);
+/** Pointer to a resource enumerator callback. */
+typedef FNKLDRENUMRSRC *PFNKLDRENUMRSRC;
+
+/** NIL resource name ID. */
+#define NIL_KLDRMOD_RSRC_NAME_ID ( ~(KU32)0 )
+/** NIL resource type ID. */
+#define NIL_KLDRMOD_RSRC_TYPE_ID ( ~(KU32)0 )
+/** @name Language ID
+ *
+ * Except for the special IDs #defined here, the values are considered
+ * format specific for now since it's only used by the PE resources.
+ *
+ * @{ */
+/** NIL language ID. */
+#define NIL_KLDR_LANG_ID ( ~(KU32)0 )
+/** Special language id value for matching any language. */
+#define KLDR_LANG_ID_ANY ( ~(KU32)1 )
+/** Special language id value indicating language neutral. */
+#define KLDR_LANG_ID_NEUTRAL ( ~(KU32)2 )
+/** Special language id value indicating user default language. */
+#define KLDR_LANG_ID_USER_DEFAULT ( ~(KU32)3 )
+/** Special language id value indicating system default language. */
+#define KLDR_LANG_ID_SYS_DEFAULT ( ~(KU32)4 )
+/** Special language id value indicating default custom locale. */
+#define KLDR_LANG_ID_CUSTOM_DEFAULT ( ~(KU32)5 )
+/** Special language id value indicating unspecified custom locale. */
+#define KLDR_LANG_ID_CUSTOM_UNSPECIFIED ( ~(KU32)6 )
+/** Special language id value indicating default custom MUI locale. */
+#define KLDR_LANG_ID_UI_CUSTOM_DEFAULT ( ~(KU32)7 )
+/** @} */
+
+/** @name KLDRMOD_OPEN_FLAGS_XXX - Module Open Flags
+ * @{ */
+/** Indicates that we won't be loading the module, we're just getting
+ * information (like symbols and line numbers) out of it. */
+#define KLDRMOD_OPEN_FLAGS_FOR_INFO K_BIT32(0)
+/** Native: Non-stub kLdrModCallInit & kLdrModCallTerm. */
+#define KLDRMOD_OPEN_FLAGS_NATIVE_ALLOW_INIT_TERM K_BIT32(1)
+/** Mask of valid flags. */
+#define KLDRMOD_OPEN_FLAGS_VALID_MASK KU32_C(0x00000003)
+/** @} */
+
+int kLdrModOpen(const char *pszFilename, KU32 fFlags, KCPUARCH enmCpuArch, PPKLDRMOD ppMod);
+int kLdrModOpenFromRdr(PKRDR pRdr, KU32 fFlags, KCPUARCH enmCpuArch, PPKLDRMOD ppMod);
+int kLdrModOpenNative(const char *pszFilename, KU32 fFlags, PPKLDRMOD ppMod);
+int kLdrModOpenNativeByHandle(KUPTR uHandle, KU32 fFlags, PPKLDRMOD ppMod);
+int kLdrModClose(PKLDRMOD pMod);
+
+int kLdrModQuerySymbol(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, KU32 iSymbol,
+ const char *pchSymbol, KSIZE cchSymbol, const char *pszVersion,
+ PFNKLDRMODGETIMPORT pfnGetForwarder, void *pvUser, PKLDRADDR puValue, KU32 *pfKind);
+int kLdrModEnumSymbols(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress,
+ KU32 fFlags, PFNKLDRMODENUMSYMS pfnCallback, void *pvUser);
+int kLdrModGetImport(PKLDRMOD pMod, const void *pvBits, KU32 iImport, char *pszName, KSIZE cchName);
+KI32 kLdrModNumberOfImports(PKLDRMOD pMod, const void *pvBits);
+int kLdrModCanExecuteOn(PKLDRMOD pMod, const void *pvBits, KCPUARCH enmArch, KCPU enmCpu);
+int kLdrModGetStackInfo(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo);
+int kLdrModQueryMainEntrypoint(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress);
+int kLdrModQueryImageUuid(PKLDRMOD pMod, const void *pvBits, void *pvUuid, KSIZE cbUuid);
+int kLdrModQueryResource(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, KU32 idType, const char *pszType,
+ KU32 idName, const char *pszName, KU32 idLang, PKLDRADDR pAddrRsrc, KSIZE *pcbRsrc);
+int kLdrModEnumResources(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, KU32 idType, const char *pszType,
+ KU32 idName, const char *pszName, KU32 idLang, PFNKLDRENUMRSRC pfnCallback, void *pvUser);
+int kLdrModEnumDbgInfo(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser);
+int kLdrModHasDbgInfo(PKLDRMOD pMod, const void *pvBits);
+int kLdrModMostlyDone(PKLDRMOD pMod);
+
+
+/** @name Operations On The Internally Managed Mapping
+ * @{ */
+int kLdrModMap(PKLDRMOD pMod);
+int kLdrModUnmap(PKLDRMOD pMod);
+int kLdrModReload(PKLDRMOD pMod);
+int kLdrModFixupMapping(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
+/** @} */
+
+/** @name Operations On The Externally Managed Mappings
+ * @{ */
+KLDRADDR kLdrModSize(PKLDRMOD pMod);
+int kLdrModGetBits(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
+int kLdrModRelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress,
+ PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
+/** @} */
+
+/** @name Operations on both internally and externally managed mappings.
+ * @{ */
+/** Special pvMapping value to pass to kLdrModAllocTLS,
+ * kLdrModFreeTLS, kLdrModCallInit, kLdrModCallTerm, and kLdrModCallThread that
+ * specifies the internal mapping (kLdrModMap). */
+#define KLDRMOD_INT_MAP ((void *)~(KUPTR)0)
+int kLdrModAllocTLS(PKLDRMOD pMod, void *pvMapping);
+void kLdrModFreeTLS(PKLDRMOD pMod, void *pvMapping);
+int kLdrModCallInit(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle);
+int kLdrModCallTerm(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle);
+int kLdrModCallThread(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle, unsigned fAttachingOrDetaching);
+/** @} */
+
+
+/**
+ * The loader module operation.
+ */
+typedef struct KLDRMODOPS
+{
+ /** The name of this module interpreter. */
+ const char *pszName;
+ /** Pointer to the next module interpreter. */
+ PCKLDRMODOPS pNext;
+
+ /**
+ * Create a loader module instance interpreting the executable image found
+ * in the specified file provider instance.
+ *
+ * @returns 0 on success and *ppMod pointing to a module instance.
+ * On failure, a non-zero OS specific error code is returned.
+ * @param pOps Pointer to the registered method table.
+ * @param pRdr The file provider instance to use.
+ * @param fFlags Flags, MBZ.
+ * @param enmCpuArch The desired CPU architecture. KCPUARCH_UNKNOWN means
+ * anything goes, but with a preference for the current
+ * host architecture.
+ * @param offNewHdr The offset of the new header in MZ files. -1 if not found.
+ * @param ppMod Where to store the module instance pointer.
+ */
+ int (* pfnCreate)(PCKLDRMODOPS pOps, PKRDR pRdr, KU32 fFlags, KCPUARCH enmCpuArch, KLDRFOFF offNewHdr, PPKLDRMOD ppMod);
+ /**
+ * Destroys an loader module instance.
+ *
+ * The caller is responsible for calling kLdrModUnmap() and kLdrFreeTLS() first.
+ *
+ * @returns 0 on success, non-zero on failure. The module instance state
+ * is unknown on failure, it's best not to touch it.
+ * @param pMod The module.
+ */
+ int (* pfnDestroy)(PKLDRMOD pMod);
+
+ /** @copydoc kLdrModQuerySymbol */
+ int (* pfnQuerySymbol)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, KU32 iSymbol,
+ const char *pchSymbol, KSIZE cchSymbol, const char *pszVersion,
+ PFNKLDRMODGETIMPORT pfnGetForwarder, void *pvUser, PKLDRADDR puValue, KU32 *pfKind);
+ /** @copydoc kLdrModEnumSymbols */
+ int (* pfnEnumSymbols)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, KU32 fFlags,
+ PFNKLDRMODENUMSYMS pfnCallback, void *pvUser);
+ /** @copydoc kLdrModGetImport */
+ int (* pfnGetImport)(PKLDRMOD pMod, const void *pvBits, KU32 iImport, char *pszName, KSIZE cchName);
+ /** @copydoc kLdrModNumberOfImports */
+ KI32 (* pfnNumberOfImports)(PKLDRMOD pMod, const void *pvBits);
+ /** @copydoc kLdrModCanExecuteOn */
+ int (* pfnCanExecuteOn)(PKLDRMOD pMod, const void *pvBits, KCPUARCH enmArch, KCPU enmCpu);
+ /** @copydoc kLdrModGetStackInfo */
+ int (* pfnGetStackInfo)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo);
+ /** @copydoc kLdrModQueryMainEntrypoint */
+ int (* pfnQueryMainEntrypoint)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress);
+ /** @copydoc kLdrModQueryImageUuid */
+ int (* pfnQueryImageUuid)(PKLDRMOD pMod, const void *pvBits, void *pvUuid, KSIZE pcbUuid);
+ /** @copydoc kLdrModQueryResource */
+ int (* pfnQueryResource)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, KU32 idType, const char *pszType,
+ KU32 idName, const char *pszName, KU32 idLang, PKLDRADDR pAddrRsrc, KSIZE *pcbRsrc);
+ /** @copydoc kLdrModEnumResources */
+ int (* pfnEnumResources)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, KU32 idType, const char *pszType,
+ KU32 idName, const char *pszName, KU32 idLang, PFNKLDRENUMRSRC pfnCallback, void *pvUser);
+ /** @copydoc kLdrModEnumDbgInfo */
+ int (* pfnEnumDbgInfo)(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser);
+ /** @copydoc kLdrModHasDbgInfo */
+ int (* pfnHasDbgInfo)(PKLDRMOD pMod, const void *pvBits);
+ /** @copydoc kLdrModMap */
+ int (* pfnMap)(PKLDRMOD pMod);
+ /** @copydoc kLdrModUnmap */
+ int (* pfnUnmap)(PKLDRMOD pMod);
+ /** @copydoc kLdrModAllocTLS */
+ int (* pfnAllocTLS)(PKLDRMOD pMod, void *pvMapping);
+ /** @copydoc kLdrModFreeTLS */
+ void (*pfnFreeTLS)(PKLDRMOD pMod, void *pvMapping);
+ /** @copydoc kLdrModReload */
+ int (* pfnReload)(PKLDRMOD pMod);
+ /** @copydoc kLdrModFixupMapping */
+ int (* pfnFixupMapping)(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
+ /** @copydoc kLdrModCallInit */
+ int (* pfnCallInit)(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle);
+ /** @copydoc kLdrModCallTerm */
+ int (* pfnCallTerm)(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle);
+ /** @copydoc kLdrModCallThread */
+ int (* pfnCallThread)(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle, unsigned fAttachingOrDetaching);
+ /** @copydoc kLdrModSize */
+ KLDRADDR (* pfnSize)(PKLDRMOD pMod);
+ /** @copydoc kLdrModGetBits */
+ int (* pfnGetBits)(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
+ /** @copydoc kLdrModRelocateBits */
+ int (* pfnRelocateBits)(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress,
+ PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
+ /** @copydoc kLdrModMostlyDone */
+ int (* pfnMostlyDone)(PKLDRMOD pMod);
+ /** Dummy which should be assigned a non-zero value. */
+ KU32 uEndOfStructure;
+} KLDRMODOPS;
+
+
+/** @} */
+
+
+
+
+/** @defgroup grp_kLdrDyld kLdrDyld - The dynamic loader
+ * @{ */
+
+/** The handle to a dynamic loader module. */
+typedef struct KLDRDYLDMOD *HKLDRMOD;
+/** Pointer to the handle to a dynamic loader module. */
+typedef HKLDRMOD *PHKLDRMOD;
+/** NIL handle value. */
+#define NIL_HKLDRMOD ((HKLDRMOD)0)
+
+
+/**
+ * File search method.
+ *
+ * In addition to it's own way of finding files, kLdr emulates
+ * the methods employed by the most popular systems.
+ */
+typedef enum KLDRDYLDSEARCH
+{
+ /** The usual invalid file search method. */
+ KLDRDYLD_SEARCH_INVALID = 0,
+ /** Uses the kLdr file search method.
+ * @todo invent me. */
+ KLDRDYLD_SEARCH_KLDR,
+ /** Use the emulation closest to the host system. */
+ KLDRDYLD_SEARCH_HOST,
+ /** Emulate the OS/2 file search method.
+ * On non-OS/2 systems, BEGINLIBPATH, LIBPATH, ENDLIBPATH and LIBPATHSTRICT are
+ * taken form the environment. */
+ KLDRDYLD_SEARCH_OS2,
+ /** Emulate the standard window file search method. */
+ KLDRDYLD_SEARCH_WINDOWS,
+ /** Emulate the alternative window file search method. */
+ KLDRDYLD_SEARCH_WINDOWS_ALTERED,
+ /** Emulate the most common UNIX file search method. */
+ KLDRDYLD_SEARCH_UNIX_COMMON,
+ /** End of the valid file search method values. */
+ KLDRDYLD_SEARCH_END,
+ /** Hack to blow the type up to 32-bit. */
+ KLDRDYLD_SEARCH_32BIT_HACK = 0x7fffffff
+} KLDRDYLDSEARCH;
+
+/** @name kLdrDyldLoad and kLdrDyldFindByName flags.
+ * @{ */
+/** The symbols in the module should be loaded into the global unix namespace.
+ * If not specified, the symbols are local and can only be referenced directly. */
+#define KLDRYDLD_LOAD_FLAGS_GLOBAL_SYMBOLS 0x00000001
+/** The symbols in the module should be loaded into the global unix namespace and
+ * it's symbols should take precedence over all currently loaded modules.
+ * This implies KLDRYDLD_LOAD_FLAGS_GLOBAL_SYMBOLS. */
+#define KLDRYDLD_LOAD_FLAGS_DEEP_SYMBOLS 0x00000002
+/** The module shouldn't be found by a global module search.
+ * If not specified, the module can be found by unspecified module searches,
+ * typical used when loading import/dep modules. */
+#define KLDRYDLD_LOAD_FLAGS_SPECIFIC_MODULE 0x00000004
+/** Do a recursive initialization calls instead of defering them to the outermost call. */
+#define KLDRDYLD_LOAD_FLAGS_RECURSIVE_INIT 0x00000008
+/** We're loading the executable module.
+ * @internal */
+#define KLDRDYLD_LOAD_FLAGS_EXECUTABLE 0x40000000
+/** @} */
+
+
+int kLdrDyldLoad(const char *pszDll, const char *pszPrefix, const char *pszSuffix, KLDRDYLDSEARCH enmSearch,
+ unsigned fFlags, PHKLDRMOD phMod, char *pszErr, KSIZE cchErr);
+int kLdrDyldUnload(HKLDRMOD hMod);
+int kLdrDyldFindByName(const char *pszDll, const char *pszPrefix, const char *pszSuffix, KLDRDYLDSEARCH enmSearch,
+ unsigned fFlags, PHKLDRMOD phMod);
+int kLdrDyldFindByAddress(KUPTR Address, PHKLDRMOD phMod, KU32 *piSegment, KUPTR *poffSegment);
+int kLdrDyldGetName(HKLDRMOD hMod, char *pszName, KSIZE cchName);
+int kLdrDyldGetFilename(HKLDRMOD hMod, char *pszFilename, KSIZE cchFilename);
+int kLdrDyldQuerySymbol(HKLDRMOD hMod, KU32 uSymbolOrdinal, const char *pszSymbolName,
+ const char *pszSymbolVersion, KUPTR *pValue, KU32 *pfKind);
+int kLdrDyldQueryResource(HKLDRMOD hMod, KU32 idType, const char *pszType, KU32 idName,
+ const char *pszName, KU32 idLang, void **pvRsrc, KSIZE *pcbRsrc);
+int kLdrDyldEnumResources(HKLDRMOD hMod, KU32 idType, const char *pszType, KU32 idName,
+ const char *pszName, KU32 idLang, PFNKLDRENUMRSRC pfnCallback, void *pvUser);
+
+
+/** @name OS/2 like API
+ * @{ */
+#if defined(__OS2__)
+# define KLDROS2API _System
+#else
+# define KLDROS2API
+#endif
+int kLdrDosLoadModule(char *pszObject, KSIZE cbObject, const char *pszModule, PHKLDRMOD phMod);
+int kLdrDosFreeModule(HKLDRMOD hMod);
+int kLdrDosQueryModuleHandle(const char *pszModname, PHKLDRMOD phMod);
+int kLdrDosQueryModuleName(HKLDRMOD hMod, KSIZE cchName, char *pszName);
+int kLdrDosQueryProcAddr(HKLDRMOD hMod, KU32 iOrdinal, const char *pszProcName, void **ppvProcAddr);
+int kLdrDosQueryProcType(HKLDRMOD hMod, KU32 iOrdinal, const char *pszProcName, KU32 *pfProcType);
+int kLdrDosQueryModFromEIP(PHKLDRMOD phMod, KU32 *piObject, KSIZE cbName, char *pszName, KUPTR *poffObject, KUPTR ulEIP);
+int kLdrDosReplaceModule(const char *pszOldModule, const char *pszNewModule, const char *pszBackupModule);
+int kLdrDosGetResource(HKLDRMOD hMod, KU32 idType, KU32 idName, void **pvResAddr);
+int kLdrDosQueryResourceSize(HKLDRMOD hMod, KU32 idType, KU32 idName, KU32 *pcb);
+int kLdrDosFreeResource(void *pvResAddr);
+/** @} */
+
+/** @name POSIX like API
+ * @{ */
+HKLDRMOD kLdrDlOpen(const char *pszLibrary, int fFlags);
+const char *kLdrDlError(void);
+void * kLdrDlSym(HKLDRMOD hMod, const char *pszSymbol);
+int kLdrDlClose(HKLDRMOD hMod);
+/** @todo GNU extensions */
+/** @} */
+
+/** @name Win32 like API
+ * @{ */
+#if defined(_MSC_VER)
+# define KLDRWINAPI __stdcall
+#else
+# define KLDRWINAPI
+#endif
+HKLDRMOD KLDRWINAPI kLdrWLoadLibrary(const char *pszFilename);
+HKLDRMOD KLDRWINAPI kLdrWLoadLibraryEx(const char *pszFilename, void *hFileReserved, KU32 fFlags);
+KU32 KLDRWINAPI kLdrWGetModuleFileName(HKLDRMOD hMod, char *pszModName, KSIZE cchModName);
+HKLDRMOD KLDRWINAPI kLdrWGetModuleHandle(const char *pszFilename);
+int KLDRWINAPI kLdrWGetModuleHandleEx(KU32 fFlags, const char *pszFilename, HKLDRMOD hMod);
+void * KLDRWINAPI kLdrWGetProcAddress(HKLDRMOD hMod, const char *pszProcName);
+KU32 KLDRWINAPI kLdrWGetDllDirectory(KSIZE cchDir, char *pszDir);
+int KLDRWINAPI kLdrWSetDllDirectory(const char *pszDir);
+int KLDRWINAPI kLdrWFreeLibrary(HKLDRMOD hMod);
+int KLDRWINAPI kLdrWDisableThreadLibraryCalls(HKLDRMOD hMod);
+
+/** The handle to a resource that's been found. */
+typedef struct KLDRWRSRCFOUND *HKLDRWRSRCFOUND;
+/** The handle to a loaded resource. */
+typedef struct KLDRWRSRCLOADED *HKLDRWRSRCLOADED;
+HKLDRWRSRCFOUND KLDRWINAPI kLdrWFindResource(HKLDRMOD hMod, const char *pszType, const char *pszName);
+HKLDRWRSRCFOUND KLDRWINAPI kLdrWFindResourceEx(HKLDRMOD hMod, const char *pszType, const char *pszName, KU16 idLang);
+KU32 KLDRWINAPI kLdrWSizeofResource(HKLDRMOD hMod, HKLDRWRSRCFOUND hFoundRsrc);
+HKLDRWRSRCLOADED KLDRWINAPI kLdrWLoadResource(HKLDRMOD hMod, HKLDRWRSRCFOUND hFoundRsrc);
+void *KLDRWINAPI kLdrWLockResource(HKLDRMOD hMod, HKLDRWRSRCLOADED hLoadedRsrc);
+int KLDRWINAPI kLdrWFreeResource(HKLDRMOD hMod, HKLDRWRSRCLOADED hLoadedRsrc);
+
+typedef int (KLDRWINAPI *PFNKLDRWENUMRESTYPE)(HKLDRMOD hMod, const char *pszType, KUPTR uUser);
+int KLDRWINAPI kLdrWEnumResourceTypes(HKLDRMOD hMod, PFNKLDRWENUMRESTYPE pfnEnum, KUPTR uUser);
+int KLDRWINAPI kLdrWEnumResourceTypesEx(HKLDRMOD hMod, PFNKLDRWENUMRESTYPE pfnEnum, KUPTR uUser, KU32 fFlags, KU16 idLang);
+
+typedef int (KLDRWINAPI *PFNKLDRWENUMRESNAME)(HKLDRMOD hMod, const char *pszType, char *pszName, KUPTR uUser);
+int KLDRWINAPI kLdrWEnumResourceNames(HKLDRMOD hMod, const char *pszType, PFNKLDRWENUMRESNAME pfnEnum, KUPTR uUser);
+int KLDRWINAPI kLdrWEnumResourceNamesEx(HKLDRMOD hMod, const char *pszType, PFNKLDRWENUMRESNAME pfnEnum, KUPTR uUser, KU32 fFlags, KU16 idLang);
+
+typedef int (KLDRWINAPI *PFNKLDRWENUMRESLANG)(HKLDRMOD hMod, const char *pszType, const char *pszName, KU16 idLang, KUPTR uUser);
+int KLDRWINAPI kLdrWEnumResourceLanguages(HKLDRMOD hMod, const char *pszType, const char *pszName, PFNKLDRWENUMRESLANG pfnEnum, KUPTR uUser);
+int KLDRWINAPI kLdrWEnumResourceLanguagesEx(HKLDRMOD hMod, const char *pszType, const char *pszName,
+ PFNKLDRWENUMRESLANG pfnEnum, KUPTR uUser, KU32 fFlags, KU16 idLang);
+/** @} */
+
+
+/** @name Process Bootstrapping
+ * @{ */
+
+/**
+ * Argument package from the stub.
+ */
+typedef struct KLDREXEARGS
+{
+ /** Load & search flags, some which will become defaults. */
+ KU32 fFlags;
+ /** The default search method. */
+ KLDRDYLDSEARCH enmSearch;
+ /** The executable file that the stub is supposed to load. */
+ char szExecutable[260];
+ /** The default prefix used when searching for DLLs. */
+ char szDefPrefix[16];
+ /** The default suffix used when searching for DLLs. */
+ char szDefSuffix[16];
+ /** The LD_LIBRARY_PATH prefix for the process.. */
+ char szLibPath[4096 - sizeof(KU32) - sizeof(KLDRDYLDSEARCH) - 16 - 16 - 260];
+} KLDREXEARGS, *PKLDREXEARGS;
+/** Pointer to a const argument package from the stub. */
+typedef const KLDREXEARGS *PCKLDREXEARGS;
+
+void kLdrLoadExe(PCKLDREXEARGS pArgs, void *pvOS); /** @todo fix this mess... */
+void kLdrDyldLoadExe(PCKLDREXEARGS pArgs, void *pvOS);
+/** @} */
+
+/** @} */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kLdrFmts/lx.h b/src/lib/kStuff/include/k/kLdrFmts/lx.h
new file mode 100644
index 0000000..fc1d1e2
--- /dev/null
+++ b/src/lib/kStuff/include/k/kLdrFmts/lx.h
@@ -0,0 +1,485 @@
+/* $Id $ */
+/** @file
+ * LX structures, types and defines.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kLdrFmts_lx_h___
+#define ___k_kLdrFmts_lx_h___
+
+#include <k/kDefs.h>
+#include <k/kTypes.h>
+
+
+#ifndef IMAGE_OS2_SIGNATURE_LX
+/** LX signature ("LX") */
+# define IMAGE_LX_SIGNATURE K_LE2H_U16('L' | ('X' << 8))
+#endif
+
+#pragma pack(1)
+
+/**
+ * Linear eXecutable header.
+ * This structure is exactly 196 bytes long.
+ */
+struct e32_exe
+{
+ KU8 e32_magic[2];
+ KU8 e32_border;
+ KU8 e32_worder;
+ KU32 e32_level;
+ KU16 e32_cpu;
+ KU16 e32_os;
+ KU32 e32_ver;
+ KU32 e32_mflags;
+ KU32 e32_mpages;
+ KU32 e32_startobj;
+ KU32 e32_eip;
+ KU32 e32_stackobj;
+ KU32 e32_esp;
+ KU32 e32_pagesize;
+ KU32 e32_pageshift;
+ /** The size of the fixup section.
+ * The fixup section consists of the fixup page table, the fixup record table,
+ * the import module table, and the import procedure name table.
+ */
+ KU32 e32_fixupsize;
+ KU32 e32_fixupsum;
+ /** The size of the resident loader section.
+ * This includes the object table, the object page map table, the resource table, the resident name table,
+ * the entry table, the module format directives table, and the page checksum table (?). */
+ KU32 e32_ldrsize;
+ /** The checksum of the loader section. 0 if not calculated. */
+ KU32 e32_ldrsum;
+ /** The offset of the object table relative to this structure. */
+ KU32 e32_objtab;
+ /** Count of objects. */
+ KU32 e32_objcnt;
+ /** The offset of the object page map table relative to this structure. */
+ KU32 e32_objmap;
+ /** The offset of the object iterated pages (whatever this is used for) relative to the start of the file. */
+ KU32 e32_itermap;
+ /** The offset of the resource table relative to this structure. */
+ KU32 e32_rsrctab;
+ /** The number of entries in the resource table. */
+ KU32 e32_rsrccnt;
+ /** The offset of the resident name table relative to this structure. */
+ KU32 e32_restab;
+ /** The offset of the entry (export) table relative to this structure. */
+ KU32 e32_enttab;
+ /** The offset of the module format directives table relative to this structure. */
+ KU32 e32_dirtab;
+ /** The number of entries in the module format directives table. */
+ KU32 e32_dircnt;
+ /** The offset of the fixup page table relative to this structure. */
+ KU32 e32_fpagetab;
+ /** The offset of the fixup record table relative to this structure. */
+ KU32 e32_frectab;
+ /** The offset of the import module name table relative to this structure. */
+ KU32 e32_impmod;
+ /** The number of entries in the import module name table. */
+ KU32 e32_impmodcnt;
+ /** The offset of the import procedure name table relative to this structure. */
+ KU32 e32_impproc;
+ /** The offset of the page checksum table relative to this structure. */
+ KU32 e32_pagesum;
+ /** The offset of the data pages relative to the start of the file. */
+ KU32 e32_datapage;
+ /** The number of preload pages (ignored). */
+ KU32 e32_preload;
+ /** The offset of the non-resident name table relative to the start of the file. */
+ KU32 e32_nrestab;
+ /** The size of the non-resident name table. */
+ KU32 e32_cbnrestab;
+ KU32 e32_nressum;
+ KU32 e32_autodata;
+ KU32 e32_debuginfo;
+ KU32 e32_debuglen;
+ KU32 e32_instpreload;
+ KU32 e32_instdemand;
+ KU32 e32_heapsize;
+ KU32 e32_stacksize;
+ KU8 e32_res3[20];
+};
+
+/** e32_magic[0] */
+#define E32MAGIC1 'L'
+/** e32_magic[1] */
+#define E32MAGIC2 'X'
+/** MAKEWORD(e32_magic[0], e32_magic[1]) */
+#define E32MAGIC 0x584c
+/** e32_border - little endian */
+#define E32LEBO 0
+/** e32_border - big endian */
+#define E32BEBO 1
+/** e32_worder - little endian */
+#define E32LEWO 0
+/** e32_worder - big endian */
+#define E32BEWO 1
+/** e32_level */
+#define E32LEVEL KU32_C(0)
+/** e32_cpu - 80286 */
+#define E32CPU286 1
+/** e32_cpu - 80386 */
+#define E32CPU386 2
+/** e32_cpu - 80486 */
+#define E32CPU486 3
+/** e32_pagesize */
+#define OBJPAGELEN KU32_C(0x1000)
+
+
+/** @name e32_mflags
+ * @{ */
+/** App Type: Fullscreen only. */
+#define E32NOPMW KU32_C(0x00000100)
+/** App Type: PM API. */
+#define E32PMAPI KU32_C(0x00000300)
+/** App Type: PM VIO compatible. */
+#define E32PMW KU32_C(0x00000200)
+/** Application type mask. */
+#define E32APPMASK KU32_C(0x00000300)
+/** Executable module. */
+#define E32MODEXE KU32_C(0x00000000)
+/** Dynamic link library (DLL / library) module. */
+#define E32MODDLL KU32_C(0x00008000)
+/** Protected memory DLL. */
+#define E32PROTDLL KU32_C(0x00010000)
+/** Physical Device Driver. */
+#define E32MODPDEV KU32_C(0x00020000)
+/** Virtual Device Driver. */
+#define E32MODVDEV KU32_C(0x00028000)
+/** Device driver */
+#define E32DEVICE E32MODPDEV
+/** Dynamic link library (DLL / library) module. */
+#define E32NOTP E32MODDLL
+/** Protected memory DLL. */
+#define E32MODPROTDLL (E32MODDLL | E32PROTDLL)
+/** Module Type mask. */
+#define E32MODMASK KU32_C(0x00038000)
+/** Not loadable (linker error). */
+#define E32NOLOAD KU32_C(0x00002000)
+/** No internal fixups. */
+#define E32NOINTFIX KU32_C(0x00000010)
+/** No external fixups (i.e. imports). */
+#define E32NOEXTFIX KU32_C(0x00000020)
+/** System DLL, no internal fixups. */
+#define E32SYSDLL KU32_C(0x00000008)
+/** Global (set) or per instance (cleared) library initialization. */
+#define E32LIBINIT KU32_C(0x00000004)
+/** Global (set) or per instance (cleared) library termination. */
+#define E32LIBTERM KU32_C(0x40000000)
+/** Indicates when set in an executable that the process isn't SMP safe. */
+#define E32NOTMPSAFE KU32_C(0x00080000)
+/** @} */
+
+/** @name Relocations (aka Fixups).
+ * @{ */
+typedef union _offset
+{
+ KU16 offset16;
+ KU32 offset32;
+} offset;
+
+/** A relocation.
+ * @remark this structure isn't very usable since LX relocations comes in too many size variations.
+ */
+struct r32_rlc
+{
+ KU8 nr_stype;
+ KU8 nr_flags;
+ KI16 r32_soff;
+ KU16 r32_objmod;
+
+ union targetid
+ {
+ offset intref;
+ union extfixup
+ {
+ offset proc;
+ KU32 ord;
+ } extref;
+ struct addfixup
+ {
+ KU16 entry;
+ offset addval;
+ } addfix;
+ } r32_target;
+ KU16 r32_srccount;
+ KU16 r32_chain;
+};
+
+/** @name Some attempt at size constanstants.
+ * @{
+ */
+#define RINTSIZE16 8
+#define RINTSIZE32 10
+#define RORDSIZE 8
+#define RNAMSIZE16 8
+#define RNAMSIZE32 10
+#define RADDSIZE16 10
+#define RADDSIZE32 12
+/** @} */
+
+/** @name nr_stype (source flags)
+ * @{ */
+#define NRSBYT 0x00
+#define NRSSEG 0x02
+#define NRSPTR 0x03
+#define NRSOFF 0x05
+#define NRPTR48 0x06
+#define NROFF32 0x07
+#define NRSOFF32 0x08
+#define NRSTYP 0x0f
+#define NRSRCMASK 0x0f
+#define NRALIAS 0x10
+#define NRCHAIN 0x20
+/** @} */
+
+/** @name nr_flags (target flags)
+ * @{ */
+#define NRRINT 0x00
+#define NRRORD 0x01
+#define NRRNAM 0x02
+#define NRRENT 0x03
+#define NRRTYP 0x03
+#define NRADD 0x04
+#define NRICHAIN 0x08
+#define NR32BITOFF 0x10
+#define NR32BITADD 0x20
+#define NR16OBJMOD 0x40
+#define NR8BITORD 0x80
+/** @} */
+
+/** @} */
+
+
+/** @name The Object Table (aka segment table)
+ * @{ */
+
+/** The Object Table Entry. */
+struct o32_obj
+{
+ /** The size of the object. */
+ KU32 o32_size;
+ /** The base address of the object. */
+ KU32 o32_base;
+ /** Object flags. */
+ KU32 o32_flags;
+ /** Page map index. */
+ KU32 o32_pagemap;
+ /** Page map size. (doesn't need to be o32_size >> page shift). */
+ KU32 o32_mapsize;
+ /** Reserved */
+ KU32 o32_reserved;
+};
+
+/** @name o32_flags
+ * @{ */
+/** Read access. */
+#define OBJREAD KU32_C(0x00000001)
+/** Write access. */
+#define OBJWRITE KU32_C(0x00000002)
+/** Execute access. */
+#define OBJEXEC KU32_C(0x00000004)
+/** Resource object. */
+#define OBJRSRC KU32_C(0x00000008)
+/** The object is discarable (i.e. don't swap, just load in pages from the executable).
+ * This overlaps a bit with object type. */
+#define OBJDISCARD KU32_C(0x00000010)
+/** The object is shared. */
+#define OBJSHARED KU32_C(0x00000020)
+/** The object has preload pages. */
+#define OBJPRELOAD KU32_C(0x00000040)
+/** The object has invalid pages. */
+#define OBJINVALID KU32_C(0x00000080)
+/** Non-permanent, link386 bug. */
+#define LNKNONPERM KU32_C(0x00000600)
+/** Non-permanent, correct 'value'. */
+#define OBJNONPERM KU32_C(0x00000000)
+/** Obj Type: The object is permanent and swappable. */
+#define OBJPERM KU32_C(0x00000100)
+/** Obj Type: The object is permanent and resident (i.e. not swappable). */
+#define OBJRESIDENT KU32_C(0x00000200)
+/** Obj Type: The object is resident and contigious. */
+#define OBJCONTIG KU32_C(0x00000300)
+/** Obj Type: The object is permanent and long locable. */
+#define OBJDYNAMIC KU32_C(0x00000400)
+/** Object type mask. */
+#define OBJTYPEMASK KU32_C(0x00000700)
+/** x86: The object require an 16:16 alias. */
+#define OBJALIAS16 KU32_C(0x00001000)
+/** x86: Big/Default selector setting, i.e. toggle 32-bit or 16-bit. */
+#define OBJBIGDEF KU32_C(0x00002000)
+/** x86: conforming selector setting (weird stuff). */
+#define OBJCONFORM KU32_C(0x00004000)
+/** x86: IOPL. */
+#define OBJIOPL KU32_C(0x00008000)
+/** @} */
+
+/** A Object Page Map Entry. */
+struct o32_map
+{
+ /** The file offset of the page. */
+ KU32 o32_pagedataoffset;
+ /** The number of bytes of raw page data. */
+ KU16 o32_pagesize;
+ /** Per page flags describing how the page is encoded in the file. */
+ KU16 o32_pageflags;
+};
+
+/** @name o32 o32_pageflags
+ * @{
+ */
+/** Raw page (uncompressed) in the file. */
+#define VALID KU16_C(0x0000)
+/** RLE encoded page in file. */
+#define ITERDATA KU16_C(0x0001)
+/** Invalid page, nothing in the file. */
+#define INVALID KU16_C(0x0002)
+/** Zero page, nothing in file. */
+#define ZEROED KU16_C(0x0003)
+/** range of pages (what is this?) */
+#define RANGE KU16_C(0x0004)
+/** Compressed page in file. */
+#define ITERDATA2 KU16_C(0x0005)
+/** @} */
+
+
+/** Iteration Record format (RLE compressed page). */
+struct LX_Iter
+{
+ /** Number of iterations. */
+ KU16 LX_nIter;
+ /** The number of bytes that's being iterated. */
+ KU16 LX_nBytes;
+ /** The bytes. */
+ KU8 LX_Iterdata;
+};
+
+/** @} */
+
+
+/** A Resource Table Entry */
+struct rsrc32
+{
+ /** Resource Type. */
+ KU16 type;
+ /** Resource ID. */
+ KU16 name;
+ /** Resource size in bytes. */
+ KU32 cb;
+ /** The index of the object containing the resource. */
+ KU16 obj;
+ /** Offset of the resource that within the object. */
+ KU32 offset;
+};
+
+
+/** @name The Entry Table (aka Export Table)
+ * @{ */
+
+/** Entry bundle.
+ * Header descripting up to 255 entries that follows immediatly after this structure. */
+struct b32_bundle
+{
+ /** The number of entries. */
+ KU8 b32_cnt;
+ /** The type of bundle. */
+ KU8 b32_type;
+ /** The index of the object containing these entry points. */
+ KU16 b32_obj;
+};
+
+/** @name b32_type
+ * @{ */
+/** Empty bundle, filling up unused ranges of ordinals. */
+#define EMPTY 0x00
+/** 16-bit offset entry point. */
+#define ENTRY16 0x01
+/** 16-bit callgate entry point. */
+#define GATE16 0x02
+/** 32-bit offset entry point. */
+#define ENTRY32 0x03
+/** Forwarder entry point. */
+#define ENTRYFWD 0x04
+/** Typing information present indicator. */
+#define TYPEINFO 0x80
+/** @} */
+
+
+/** Entry point. */
+struct e32_entry
+{
+ /** Entry point flags */
+ KU8 e32_flags; /* Entry point flags */
+ union entrykind
+ {
+ /** ENTRY16 or ENTRY32. */
+ offset e32_offset;
+ /** GATE16 */
+ struct callgate
+ {
+ /** Offset into segment. */
+ KU16 offset;
+ /** The callgate selector */
+ KU16 callgate;
+ } e32_callgate;
+ /** ENTRYFWD */
+ struct fwd
+ {
+ /** Module ordinal number (i.e. into the import module table). */
+ KU16 modord;
+ /** Procedure name or ordinal number. */
+ KU32 value;
+ } e32_fwd;
+ } e32_variant;
+};
+
+/** @name e32_flags
+ * @{ */
+/** Exported entry (set) or private entry (clear). */
+#define E32EXPORT 0x01
+/** Uses shared data. */
+#define E32SHARED 0x02
+/** Parameter word count mask. */
+#define E32PARAMS 0xf8
+/** ENTRYFWD: Imported by ordinal (set) or by name (clear). */
+#define FWD_ORDINAL 0x01
+/** @} */
+
+/** @name dunno
+ * @{ */
+#define FIXENT16 3
+#define FIXENT32 5
+#define GATEENT16 5
+#define FWDENT 7
+/** @} */
+
+#pragma pack()
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kLdrFmts/mach-o.h b/src/lib/kStuff/include/k/kLdrFmts/mach-o.h
new file mode 100644
index 0000000..61f908c
--- /dev/null
+++ b/src/lib/kStuff/include/k/kLdrFmts/mach-o.h
@@ -0,0 +1,997 @@
+/* $Id: mach-o.h 63 2013-10-30 02:00:14Z bird $ */
+/** @file
+ * Mach-0 structures, types and defines.
+ */
+
+/*
+ * Copyright (c) 2006-2012 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.
+ */
+
+#ifndef ___k_kLdrFmts_mach_o_h___
+#define ___k_kLdrFmts_mach_o_h___
+
+#include <k/kDefs.h>
+#include <k/kTypes.h>
+
+
+/** @defgroup grp_mach_o The Mach-O Structures, Types, and Defines.
+ * @{
+ */
+
+
+#ifndef IMAGE_FAT_SIGNATURE
+/** The FAT signature (universal binaries). */
+# define IMAGE_FAT_SIGNATURE KU32_C(0xcafebabe)
+#endif
+#ifndef IMAGE_FAT_SIGNATURE_OE
+/** The FAT signature (universal binaries), other endian. */
+# define IMAGE_FAT_SIGNATURE_OE KU32_C(0xbebafeca)
+#endif
+
+/**
+ * The fat header found at the start of universal binaries.
+ * It is followed by \a nfat_arch numbers of \a fat_arch structures.
+ */
+typedef struct fat_header
+{
+ KU32 magic;
+ KU32 nfat_arch;
+} fat_header_t;
+
+/**
+ * Description of fat file item.
+ */
+typedef struct fat_arch
+{
+ KI32 cputype;
+ KI32 cpusubtype;
+ KU32 offset;
+ KU32 size;
+ KU32 align; /**< Power of 2. */
+} fat_arch_t;
+
+
+
+#ifndef IMAGE_MACHO32_SIGNATURE
+/** The 32-bit Mach-O signature. */
+# define IMAGE_MACHO32_SIGNATURE KU32_C(0xfeedface)
+#endif
+#ifndef IMAGE_MACHO32_SIGNATURE_OE
+/** The 32-bit Mach-O signature, other endian. */
+# define IMAGE_MACHO32_SIGNATURE_OE KU32_C(0xcefaedfe)
+#endif
+#define MH_MAGIC IMAGE_MACHO32_SIGNATURE
+#define MH_CIGAM IMAGE_MACHO32_SIGNATURE_OE
+
+/**
+ * 32-bit Mach-O header.
+ * This is followed by \a ncmds number of load commands.
+ * @see mach_header_64
+ */
+typedef struct mach_header_32
+{
+ KU32 magic;
+ KI32 cputype;
+ KI32 cpusubtype;
+ KU32 filetype;
+ KU32 ncmds;
+ KU32 sizeofcmds;
+ KU32 flags;
+} mach_header_32_t;
+
+
+
+#ifndef IMAGE_MACHO64_SIGNATURE
+/** The 64-bit Mach-O signature. */
+# define IMAGE_MACHO64_SIGNATURE KU32_C(0xfeedfacf)
+#endif
+#ifndef IMAGE_MACHO64_SIGNATURE_OE
+/** The 64-bit Mach-O signature, other endian. */
+# define IMAGE_MACHO64_SIGNATURE_OE KU32_C(0xfefaedfe)
+#endif
+#define MH_MAGIC_64 IMAGE_MACHO64_SIGNATURE
+#define MH_CIGAM_64 IMAGE_MACHO64_SIGNATURE_OE
+
+/**
+ * 64-bit Mach-O header.
+ * This is followed by \a ncmds number of load commands.
+ * @see mach_header
+ */
+typedef struct mach_header_64
+{
+ KU32 magic;
+ KI32 cputype;
+ KI32 cpusubtype;
+ KU32 filetype;
+ KU32 ncmds;
+ KU32 sizeofcmds;
+ KU32 flags;
+ KU32 reserved; /**< (for proper struct and command alignment I guess) */
+} mach_header_64_t;
+
+
+/** @name File types (mach_header_64::filetype, mach_header_32::filetype)
+ * @{
+ */
+#define MH_OBJECT KU32_C(1) /**< Object (relocatable). */
+#define MH_EXECUTE KU32_C(2) /**< Executable (demand paged). */
+#define MH_FVMLIB KU32_C(3) /**< Fixed VM shared library. */
+#define MH_CORE KU32_C(4) /**< Core file. */
+#define MH_PRELOAD KU32_C(5) /**< Preloaded executable. */
+#define MH_DYLIB KU32_C(6) /**< Dynamically bound shared library. */
+#define MH_DYLINKER KU32_C(7) /**< Dynamic linker. */
+#define MH_BUNDLE KU32_C(8) /**< Dymamically bound bundle. */
+#define MH_DYLIB_STUB KU32_C(9) /**< Shared library stub for static linking. */
+#define MH_DSYM KU32_C(10)/**< Debug symbols. */
+#define MH_KEXT_BUNDLE KU32_C(11)/**< Kernel extension (introduced with the AMD64 kernel). */
+
+/** @} */
+
+
+/** @name Mach-O Header flags (mach_header_64::flags, mach_header_32::flags)
+ * @{
+ */
+#define MH_NOUNDEFS KU32_C(0x00000001) /**< No undefined symbols. */
+#define MH_INCRLINK KU32_C(0x00000002) /**< Partial increment link output. */
+#define MH_DYLDLINK KU32_C(0x00000004) /**< Food for the dynamic linker, not for ld. */
+#define MH_BINDATLOAD KU32_C(0x00000008) /**< Bind all undefined symbols at load time. */
+#define MH_PREBOUND KU32_C(0x00000010) /**< Contains prebound undefined symbols. */
+#define MH_SPLIT_SEGS KU32_C(0x00000020) /**< Read-only and read-write segments are split. */
+#define MH_LAZY_INIT KU32_C(0x00000040) /**< Obsolete flag for doing lazy init when data is written. */
+#define MH_TWOLEVEL KU32_C(0x00000080) /**< Uses two-level name space bindings. */
+#define MH_FORCE_FLAT KU32_C(0x00000100) /**< Task: The executable forces all images to use flat name space bindings. */
+#define MH_NOMULTIDEFS KU32_C(0x00000200) /**< No multiple symbol definitions, safe to use two-level namespace hints. */
+#define MH_NOFIXPREBINDING KU32_C(0x00000400) /**< The dynamic linker should not notify the prebinding agent about this executable. */
+#define MH_PREBINDABLE KU32_C(0x00000800) /**< Not prebound, but it can be. Invalid if MH_PREBOUND is set. */
+#define MH_ALLMODSBOUND KU32_C(0x00001000) /**< Binds to all two-level namespace modules of preqs. Requires MH_PREBINDABLE and MH_TWOLEVEL to be set. */
+#define MH_SUBSECTIONS_VIA_SYMBOLS KU32_C(0x00002000) /**< Safe to divide sections into sub-sections via symbols for dead code stripping. */
+#define MH_CANONICAL KU32_C(0x00004000) /**< Canonicalized via unprebind. */
+#define MH_WEAK_DEFINES KU32_C(0x00008000) /**< The (finally) linked image has weak symbols. */
+#define MH_BINDS_TO_WEAK KU32_C(0x00010000) /**< The (finally) linked image uses weak symbols. */
+#define MH_ALLOW_STACK_EXECUTION KU32_C(0x00020000) /**< Task: allow stack execution. (MH_EXECUTE only) */
+#define MH_ROOT_SAFE KU32_C(0x00040000) /**< Binary safe for root execution. */
+#define MH_SETUID_SAFE KU32_C(0x00080000) /**< Binary safe for set-uid execution. */
+#define MH_NO_REEXPORTED_DYLIBS KU32_C(0x00100000) /**< No reexported dylibs. */
+#define MH_PIE KU32_C(0x00200000) /**< Address space randomization. (MH_EXECUTE only) */
+#define MH_DEAD_STRIPPABLE_DYLIB KU32_C(0x00400000) /**< Drop dylib dependency if not used. (MH_DYLIB only) */
+#define MH_HAS_TLV_DESCRIPTORS KU32_C(0x00800000) /**< Has a S_TRHEAD_LOCAL_VARIABLES section. TLS support. */
+#define MH_NO_HEAP_EXECUTION KU32_C(0x01000000) /**< Task: no heap execution. (MH_EXECUTE only) */
+#define MH_VALID_FLAGS KU32_C(0x01ffffff) /**< Mask containing the defined flags. */
+/** @} */
+
+
+/** @name CPU types / bits (mach_header_64::cputype, mach_header_32::cputype, fat_arch::cputype)
+ * @{
+ */
+#define CPU_ARCH_MASK KI32_C(0xff000000)
+#define CPU_ARCH_ABI64 KI32_C(0x01000000)
+#define CPU_TYPE_ANY KI32_C(-1)
+#define CPU_TYPE_VAX KI32_C(1)
+#define CPU_TYPE_MC680x0 KI32_C(6)
+#define CPU_TYPE_X86 KI32_C(7)
+#define CPU_TYPE_I386 CPU_TYPE_X86
+#define CPU_TYPE_X86_64 (CPU_TYPE_X86 | CPU_ARCH_ABI64)
+#define CPU_TYPE_MC98000 KI32_C(10)
+#define CPU_TYPE_HPPA KI32_C(11)
+#define CPU_TYPE_MC88000 KI32_C(13)
+#define CPU_TYPE_SPARC KI32_C(14)
+#define CPU_TYPE_I860 KI32_C(15)
+#define CPU_TYPE_POWERPC KI32_C(18)
+#define CPU_TYPE_POWERPC64 (CPU_TYPE_POWERPC | CPU_ARCH_ABI64)
+/** @} */
+
+
+/** @name CPU subtypes (mach_header_64::cpusubtype, mach_header_32::cpusubtype, fat_arch::cpusubtype)
+ * @{ */
+#define CPU_SUBTYPE_MULTIPLE KI32_C(-1)
+#define CPU_SUBTYPE_LITTLE_ENDIAN KI32_C(0) /**< figure this one out. */
+#define CPU_SUBTYPE_BIG_ENDIAN KI32_C(1) /**< ditto */
+
+/* VAX */
+#define CPU_SUBTYPE_VAX_ALL KI32_C(0)
+#define CPU_SUBTYPE_VAX780 KI32_C(1)
+#define CPU_SUBTYPE_VAX785 KI32_C(2)
+#define CPU_SUBTYPE_VAX750 KI32_C(3)
+#define CPU_SUBTYPE_VAX730 KI32_C(4)
+#define CPU_SUBTYPE_UVAXI KI32_C(5)
+#define CPU_SUBTYPE_UVAXII KI32_C(6)
+#define CPU_SUBTYPE_VAX8200 KI32_C(7)
+#define CPU_SUBTYPE_VAX8500 KI32_C(8)
+#define CPU_SUBTYPE_VAX8600 KI32_C(9)
+#define CPU_SUBTYPE_VAX8650 KI32_C(10)
+#define CPU_SUBTYPE_VAX8800 KI32_C(11)
+#define CPU_SUBTYPE_UVAXIII KI32_C(12)
+
+/* MC680xx */
+#define CPU_SUBTYPE_MC680x0_ALL KI32_C(1)
+#define CPU_SUBTYPE_MC68030 KI32_C(1)
+#define CPU_SUBTYPE_MC68040 KI32_C(2)
+#define CPU_SUBTYPE_MC68030_ONLY KI32_C(3)
+
+/* I386 */
+#define CPU_SUBTYPE_INTEL(fam, model) ( (KI32)(((model) << 4) | (fam)) )
+#define CPU_SUBTYPE_INTEL_FAMILY(subtype) ( (subtype) & 0xf )
+#define CPU_SUBTYPE_INTEL_MODEL(subtype) ( (subtype) >> 4 )
+#define CPU_SUBTYPE_INTEL_FAMILY_MAX 0xf
+#define CPU_SUBTYPE_INTEL_MODEL_ALL 0
+
+#define CPU_SUBTYPE_I386_ALL CPU_SUBTYPE_INTEL(3, 0)
+#define CPU_SUBTYPE_386 CPU_SUBTYPE_INTEL(3, 0)
+#define CPU_SUBTYPE_486 CPU_SUBTYPE_INTEL(4, 0)
+#define CPU_SUBTYPE_486SX CPU_SUBTYPE_INTEL(4, 8)
+#define CPU_SUBTYPE_586 CPU_SUBTYPE_INTEL(5, 0)
+#define CPU_SUBTYPE_PENT CPU_SUBTYPE_INTEL(5, 0)
+#define CPU_SUBTYPE_PENTPRO CPU_SUBTYPE_INTEL(6, 1)
+#define CPU_SUBTYPE_PENTII_M3 CPU_SUBTYPE_INTEL(6, 3)
+#define CPU_SUBTYPE_PENTII_M5 CPU_SUBTYPE_INTEL(6, 5)
+#define CPU_SUBTYPE_CELERON CPU_SUBTYPE_INTEL(7, 6)
+#define CPU_SUBTYPE_CELERON_MOBILE CPU_SUBTYPE_INTEL(7, 7)
+#define CPU_SUBTYPE_PENTIUM_3 CPU_SUBTYPE_INTEL(8, 0)
+#define CPU_SUBTYPE_PENTIUM_3_M CPU_SUBTYPE_INTEL(8, 1)
+#define CPU_SUBTYPE_PENTIUM_3_XEON CPU_SUBTYPE_INTEL(8, 2)
+#define CPU_SUBTYPE_PENTIUM_M CPU_SUBTYPE_INTEL(9, 0)
+#define CPU_SUBTYPE_PENTIUM_4 CPU_SUBTYPE_INTEL(10, 0)
+#define CPU_SUBTYPE_PENTIUM_4_M CPU_SUBTYPE_INTEL(10, 1)
+#define CPU_SUBTYPE_ITANIUM CPU_SUBTYPE_INTEL(11, 0)
+#define CPU_SUBTYPE_ITANIUM_2 CPU_SUBTYPE_INTEL(11, 1)
+#define CPU_SUBTYPE_XEON CPU_SUBTYPE_INTEL(12, 0)
+#define CPU_SUBTYPE_XEON_MP CPU_SUBTYPE_INTEL(12, 1)
+
+/* X86 */
+#define CPU_SUBTYPE_X86_ALL KI32_C(3) /* CPU_SUBTYPE_I386_ALL */
+#define CPU_SUBTYPE_X86_64_ALL KI32_C(3) /* CPU_SUBTYPE_I386_ALL */
+#define CPU_SUBTYPE_X86_ARCH1 KI32_C(4) /* CPU_SUBTYPE_I486_ALL */
+
+/* MIPS */
+#define CPU_SUBTYPE_MIPS_ALL KI32_C(0)
+#define CPU_SUBTYPE_MIPS_R2300 KI32_C(1)
+#define CPU_SUBTYPE_MIPS_R2600 KI32_C(2)
+#define CPU_SUBTYPE_MIPS_R2800 KI32_C(3)
+#define CPU_SUBTYPE_MIPS_R2000a KI32_C(4)
+#define CPU_SUBTYPE_MIPS_R2000 KI32_C(5)
+#define CPU_SUBTYPE_MIPS_R3000a KI32_C(6)
+#define CPU_SUBTYPE_MIPS_R3000 KI32_C(7)
+
+/* MC98000 (PowerPC) */
+#define CPU_SUBTYPE_MC98000_ALL KI32_C(0)
+#define CPU_SUBTYPE_MC98601 KI32_C(1)
+
+/* HP-PA */
+#define CPU_SUBTYPE_HPPA_ALL KI32_C(0)
+#define CPU_SUBTYPE_HPPA_7100 KI32_C(0)
+#define CPU_SUBTYPE_HPPA_7100LC KI32_C(1)
+
+/* MC88000 */
+#define CPU_SUBTYPE_MC88000_ALL KI32_C(0)
+#define CPU_SUBTYPE_MC88100 KI32_C(1)
+#define CPU_SUBTYPE_MC88110 KI32_C(2)
+
+/* SPARC */
+#define CPU_SUBTYPE_SPARC_ALL KI32_C(0)
+
+/* I860 */
+#define CPU_SUBTYPE_I860_ALL KI32_C(0)
+#define CPU_SUBTYPE_I860_860 KI32_C(1)
+
+/* PowerPC */
+#define CPU_SUBTYPE_POWERPC_ALL KI32_C(0)
+#define CPU_SUBTYPE_POWERPC_601 KI32_C(1)
+#define CPU_SUBTYPE_POWERPC_602 KI32_C(2)
+#define CPU_SUBTYPE_POWERPC_603 KI32_C(3)
+#define CPU_SUBTYPE_POWERPC_603e KI32_C(4)
+#define CPU_SUBTYPE_POWERPC_603ev KI32_C(5)
+#define CPU_SUBTYPE_POWERPC_604 KI32_C(6)
+#define CPU_SUBTYPE_POWERPC_604e KI32_C(7)
+#define CPU_SUBTYPE_POWERPC_620 KI32_C(8)
+#define CPU_SUBTYPE_POWERPC_750 KI32_C(9)
+#define CPU_SUBTYPE_POWERPC_7400 KI32_C(10)
+#define CPU_SUBTYPE_POWERPC_7450 KI32_C(11)
+#define CPU_SUBTYPE_POWERPC_Max KI32_C(10)
+#define CPU_SUBTYPE_POWERPC_SCVger KI32_C(11)
+#define CPU_SUBTYPE_POWERPC_970 KI32_C(100)
+
+/* Subtype capability / feature bits, added in 10.5. X86 only? */
+#define CPU_SUBTYPE_MASK KU32_C(0xff000000)
+#define CPU_SUBTYPE_LIB64 KU32_C(0x8000000)
+
+/** @} */
+
+
+
+/** @defgroup grp_macho_o_lc Load Commands
+ * @{ */
+
+/**
+ * The load command common core structure.
+ *
+ * After the Mach-O header follows an array of variable sized
+ * load command which all has this header in common.
+ */
+typedef struct load_command
+{
+ KU32 cmd; /**< The load command id. */
+ KU32 cmdsize; /**< The size of the command (including this header). */
+} load_command_t;
+
+/** @name Load Command IDs (load_command::cmd)
+ * @{
+ */
+/** Flag that when set requires the dynamic linker to fail if it doesn't
+ * grok the command. The dynamic linker will otherwise ignore commands it
+ * doesn't understand. Introduced with Mac OS X 10.1. */
+#define LC_REQ_DYLD KU32_C(0x80000000)
+
+#define LC_SEGMENT_32 KU32_C(0x01) /**< Segment to be mapped (32-bit). See segment_command_32. */
+#define LC_SYMTAB KU32_C(0x02) /**< 'stab' symbol table. See symtab_command. */
+#define LC_SYMSEG KU32_C(0x03) /**< Obsoleted gdb symbol table. */
+#define LC_THREAD KU32_C(0x04) /**< Thread. See thread_command. */
+#define LC_UNIXTHREAD KU32_C(0x05) /**< Unix thread (includes stack and stuff). See thread_command. */
+#define LC_LOADFVMLIB KU32_C(0x06) /**< Load a specified fixed VM shared library (obsolete?). See fvmlib_command. */
+#define LC_IDFVMLIB KU32_C(0x07) /**< Fixed VM shared library id (obsolete?). See fvmlib_command. */
+#define LC_IDENT KU32_C(0x08) /**< Identification info (obsolete). See ident_command. */
+#define LC_FVMFILE KU32_C(0x09) /**< Fixed VM file inclusion (internal). See fvmfile_command. */
+#define LC_PREPAGE KU32_C(0x0a) /**< Prepage command (internal). See ?? */
+#define LC_DYSYMTAB KU32_C(0x0b) /**< Symbol table for dynamic linking. See dysymtab_command. */
+#define LC_LOAD_DYLIB KU32_C(0x0c) /**< Load a dynamically linked shared library. See dylib_command. */
+#define LC_ID_DYLIB KU32_C(0x0d) /**< Dynamically linked share library ident. See dylib_command. */
+#define LC_LOAD_DYLINKER KU32_C(0x0e) /**< Load a dynamical link editor. See dylinker_command. */
+#define LC_ID_DYLINKER KU32_C(0x0f) /**< Dynamic link editor ident. See dylinker_command. */
+#define LC_PREBOUND_DYLIB KU32_C(0x10) /**< Prebound modules for dynamically linking of a shared lib. See prebound_dylib_command. */
+#define LC_ROUTINES KU32_C(0x11) /**< Image routines. See routines_command_32. */
+#define LC_SUB_FRAMEWORK KU32_C(0x12) /**< Sub framework. See sub_framework_command. */
+#define LC_SUB_UMBRELLA KU32_C(0x13) /**< Sub umbrella. See sub_umbrella_command. */
+#define LC_SUB_CLIENT KU32_C(0x14) /**< Sub client. See sub_client_command. */
+#define LC_SUB_LIBRARY KU32_C(0x15) /**< Sub library. See sub_library_command. */
+#define LC_TWOLEVEL_HINTS KU32_C(0x16) /**< Two-level namespace lookup hints. See twolevel_hints_command. */
+#define LC_PREBIND_CKSUM KU32_C(0x17) /**< Prebind checksum. See prebind_cksum_command. */
+#define LC_LOAD_WEAK_DYLIB (KU32_C(0x18) | LC_REQ_DYLD) /**< Dylib that can be missing, all symbols weak. See dylib_command. */
+#define LC_SEGMENT_64 KU32_C(0x19) /**< segment to be mapped (64-bit). See segment_command_32. */
+#define LC_ROUTINES_64 KU32_C(0x1a) /**< Image routines (64-bit). See routines_command_32. */
+#define LC_UUID KU32_C(0x1b) /**< The UUID of the object module. See uuid_command. */
+#define LC_RPATH (KU32_C(0x1c) | LC_REQ_DYLD) /**< Runpth additions. See rpath_command. */
+#define LC_CODE_SIGNATURE KU32_C(0x1d) /**< Code signature location. See linkedit_data_command. */
+#define LC_SEGMENT_SPLIT_INFO KU32_C(0x1e)/**< Segment split info location. See linkedit_data_command. */
+#define LC_REEXPORT_DYLIB (KU32_C(0x1f) | LC_REQ_DYLD)/**< Load and re-export the given dylib - DLL forwarding. See dylib_command. */
+#define LC_LAZY_LOAD_DYLIB KU32_C(0x20) /**< Delays loading of the given dylib until used. See dylib_command? */
+#define LC_ENCRYPTION_INFO KU32_C(0x21) /**< Segment encryption information. See encryption_info_command. */
+#define LC_DYLD_INFO KU32_C(0x22) /**< Compressed dylib relocation information, alternative present. See dyld_info_command. */
+#define LC_DYLD_INFO_ONLY (KU32_C(0x22) | LC_REQ_DYLD) /**< Compressed dylib relocation information, no alternative. See dyld_info_command. */
+#define LC_LOAD_UPWARD_DYLIB KU32_C(0x23) /**< ???? */
+#define LC_VERSION_MIN_MACOSX KU32_C(0x24) /**< The image requires the given Mac OS X version. See version_min_command. */
+#define LC_VERSION_MIN_IPHONEOS KU32_C(0x25) /**< The image requires the given iOS version. See version_min_command. */
+#define LC_FUNCTION_STARTS KU32_C(0x26) /**< Where to find the compress function start addresses. See linkedit_data_command. */
+#define LC_DYLD_ENVIRONMENT KU32_C(0x27) /**< Environment variable for the dynamic linker. See dylinker_command. */
+#define LC_MAIN (KU32_C(0x28) | LC_REQ_DYLD) /**< Simpler alternative to LC_UNIXTHREAD. */
+#define LC_DATA_IN_CODE KU32_C(0x29) /**< Table of data in the the text section. */
+#define LC_SOURCE_VERSION KU32_C(0x2a) /**< Source code revision / version hint. */
+#define LC_DYLIB_CODE_SIGN_DRS KU32_C(0x2b) /**< Code signing designated requirements copied from dylibs prequisites. */
+/** @} */
+
+
+/**
+ * Load Command String.
+ */
+typedef struct lc_str
+{
+ /** Offset of the string relative to the load_command structure.
+ * The string is zero-terminated. the size of the load command
+ * is zero padded up to a multiple of 4 bytes. */
+ KU32 offset;
+} lc_str_t;
+
+
+/**
+ * Segment load command (32-bit).
+ */
+typedef struct segment_command_32
+{
+ KU32 cmd; /**< LC_SEGMENT */
+ KU32 cmdsize; /**< sizeof(self) + sections. */
+ char segname[16]; /**< The segment name. */
+ KU32 vmaddr; /**< Memory address of this segment. */
+ KU32 vmsize; /**< Size of this segment. */
+ KU32 fileoff; /**< The file location of the segment. */
+ KU32 filesize; /**< The file size of the segment. */
+ KU32 maxprot; /**< Maximum VM protection. */
+ KU32 initprot; /**< Initial VM protection. */
+ KU32 nsects; /**< Number of section desciptors following this structure. */
+ KU32 flags; /**< Flags (SG_*). */
+} segment_command_32_t;
+
+
+/**
+ * Segment load command (64-bit).
+ * Same as segment_command_32 except 4 members has been blown up to 64-bit.
+ */
+typedef struct segment_command_64
+{
+ KU32 cmd; /**< LC_SEGMENT */
+ KU32 cmdsize; /**< sizeof(self) + sections. */
+ char segname[16]; /**< The segment name. */
+ KU64 vmaddr; /**< Memory address of this segment. */
+ KU64 vmsize; /**< Size of this segment. */
+ KU64 fileoff; /**< The file location of the segment. */
+ KU64 filesize; /**< The file size of the segment. */
+ KU32 maxprot; /**< Maximum VM protection. */
+ KU32 initprot; /**< Initial VM protection. */
+ KU32 nsects; /**< Number of section desciptors following this structure. */
+ KU32 flags; /**< Flags (SG_*). */
+} segment_command_64_t;
+
+/** @name Segment flags (segment_command_64::flags, segment_command_32::flags)
+ * @{ */
+/** Map the file bits in the top end of the memory area for the segment
+ * instead of the low end. Intended for stacks in core dumps.
+ * The part of the segment memory not covered by file bits will be zeroed. */
+#define SG_HIGHVM KU32_C(0x00000001)
+/** This segment is the virtual memory allocated by a fixed VM library.
+ * (Used for overlap checking in the linker.) */
+#define SG_FVMLIB KU32_C(0x00000002)
+/** No relocations for or symbols that's relocated to in this segment.
+ * The segment can therefore safely be replaced. */
+#define SG_NORELOC KU32_C(0x00000004)
+/** The segment is protected.
+ * The first page isn't protected if it starts at file offset 0
+ * (so that the mach header and this load command can be easily mapped). */
+#define SG_PROTECTED_VERSION_1 KU32_C(0x00000008)
+/** @} */
+
+
+/**
+ * 32-bit section (part of a segment load command).
+ */
+typedef struct section_32
+{
+ char sectname[16]; /**< The section name. */
+ char segname[16]; /**< The name of the segment this section goes into. */
+ KU32 addr; /**< The memory address of this section. */
+ KU32 size; /**< The size of this section. */
+ KU32 offset; /**< The file offset of this section. */
+ KU32 align; /**< The section alignment (**2). */
+ KU32 reloff; /**< The file offset of the relocations. */
+ KU32 nreloc; /**< The number of relocations. */
+ KU32 flags; /**< The section flags; section type and attribs */
+ KU32 reserved1; /**< Reserved / offset / index. */
+ KU32 reserved2; /**< Reserved / count / sizeof. */
+} section_32_t;
+
+/**
+ * 64-bit section (part of a segment load command).
+ */
+typedef struct section_64
+{
+ char sectname[16]; /**< The section name. */
+ char segname[16]; /**< The name of the segment this section goes into. */
+ KU64 addr; /**< The memory address of this section. */
+ KU64 size; /**< The size of this section. */
+ KU32 offset; /**< The file offset of this section. */
+ KU32 align; /**< The section alignment (**2). */
+ KU32 reloff; /**< The file offset of the relocations. */
+ KU32 nreloc; /**< The number of relocations. */
+ KU32 flags; /**< The section flags; section type and attribs */
+ KU32 reserved1; /**< Reserved / offset / index. */
+ KU32 reserved2; /**< Reserved / count / sizeof. */
+ KU32 reserved3; /**< (Just) Reserved. */
+} section_64_t;
+
+/** @name Section flags (section_64::flags, section_32::flags)
+ * @{
+ */
+/** Section type mask. */
+#define SECTION_TYPE KU32_C(0x000000ff)
+/** Regular section. */
+#define S_REGULAR 0x00
+/** Zero filled section. */
+#define S_ZEROFILL 0x01
+/** C literals. */
+#define S_CSTRING_LITERALS 0x02
+/** 4 byte literals. */
+#define S_4BYTE_LITERALS 0x03
+/** 8 byte literals. */
+#define S_8BYTE_LITERALS 0x04
+/** Pointer to literals. */
+#define S_LITERAL_POINTERS 0x05
+/** Section containing non-lazy symbol pointers.
+ * Reserved1 == start index in the indirect symbol table. */
+#define S_NON_LAZY_SYMBOL_POINTERS 0x06
+/** Section containing lazy symbol pointers.
+ * Reserved1 == start index in the indirect symbol table. */
+#define S_LAZY_SYMBOL_POINTERS 0x07
+/** Section containing symbol stubs.
+ * Reserved2 == stub size. */
+#define S_SYMBOL_STUBS 0x08
+/** Section containing function pointers for module initialization. . */
+#define S_MOD_INIT_FUNC_POINTERS 0x09
+/** Section containing function pointers for module termination. . */
+#define S_MOD_TERM_FUNC_POINTERS 0x0a
+/** Section containing symbols that are to be coalesced. */
+#define S_COALESCED 0x0b
+/** Zero filled section that be larger than 4GB. */
+#define S_GB_ZEROFILL 0x0c
+/** Section containing pairs of function pointers for interposing. */
+#define S_INTERPOSING 0x0d
+/** 16 byte literals. */
+#define S_16BYTE_LITERALS 0x0e
+/** DTrace byte code / definitions (DOF = DTrace object format). */
+#define S_DTRACE_DOF 0x0f
+/** Section containing pointers to symbols in lazily loaded dylibs. */
+#define S_LAZY_DYLIB_SYMBOL_POINTERS 0x10
+
+/** Section attribute mask. */
+#define SECTION_ATTRIBUTES KU32_C(0xffffff00)
+
+/** User settable attribute mask. */
+#define SECTION_ATTRIBUTES_USR KU32_C(0xff000000)
+/** Pure instruction (code). */
+#define S_ATTR_PURE_INSTRUCTIONS KU32_C(0x80000000)
+/** ranlib, ignore my symbols... */
+#define S_ATTR_NO_TOC KU32_C(0x40000000)
+/** May strip static symbols when linking int a MH_DYLDLINK file. */
+#define S_ATTR_STRIP_STATIC_SYMS KU32_C(0x20000000)
+/** No dead stripping. */
+#define S_ATTR_NO_DEAD_STRIP KU32_C(0x10000000)
+/** Live support. */
+#define S_ATTR_LIVE_SUPPORT KU32_C(0x08000000)
+/** Contains self modifying code (generally i386 code stub for dyld). */
+#define S_ATTR_SELF_MODIFYING_CODE KU32_C(0x04000000)
+/** Debug info (DWARF usually). */
+#define S_ATTR_DEBUG KU32_C(0x02000000)
+
+/** System settable attribute mask. */
+#define SECTION_ATTRIBUTES_SYS KU32_C(0x00ffff00)
+/** Contains some instructions (code). */
+#define S_ATTR_SOME_INSTRUCTIONS KU32_C(0x00000400)
+/** Has external relocations. */
+#define S_ATTR_EXT_RELOC KU32_C(0x00000200)
+/** Has internal (local) relocations. */
+#define S_ATTR_LOC_RELOC KU32_C(0x00000100)
+/** @} */
+
+/** @name Known Segment and Section Names.
+ * Some of these implies special linker behaviour.
+ * @{
+ */
+/** Page zero - not-present page for catching invalid access. (MH_EXECUTE typically) */
+#define SEG_PAGEZERO "__PAGEZERO"
+/** Traditional UNIX text segment.
+ * Defaults to R-X. */
+#define SEG_TEXT "__TEXT"
+/** The text part of SEG_TEXT. */
+#define SECT_TEXT "__text"
+/** The fvmlib initialization. */
+#define SECT_FVMLIB_INIT0 "__fvmlib_init0"
+/** The section following the fvmlib initialization. */
+#define SECT_FVMLIB_INIT1 "__fvmlib_init1"
+/** The traditional UNIX data segment. (DGROUP to DOS and OS/2 people.) */
+#define SEG_DATA "__DATA"
+/** The initialized data section. */
+#define SECT_DATA "__data"
+/** The uninitialized data section. */
+#define SECT_BSS "__bss"
+/** The common symbol section. */
+#define SECT_COMMON "__common"
+/** Objective-C runtime segment. */
+#define SEG_OBJC "__OBJC"
+/** Objective-C symbol table section. */
+#define SECT_OBJC_SYMBOLS "__symbol_table"
+/** Objective-C module information section. */
+#define SECT_OBJC_MODULES "__module_info"
+/** Objective-C string table section. */
+#define SECT_OBJC_STRINGS "__selector_strs"
+/** Objective-C string table section. */
+#define SECT_OBJC_REFS "__selector_refs"
+/** Icon segment. */
+#define SEG_ICON "__ICON"
+/** The icon headers. */
+#define SECT_ICON_HEADER "__header"
+/** The icons in the TIFF format. */
+#define SECT_ICON_TIFF "__tiff"
+/** ld -seglinkedit segment containing all the structs create and maintained
+ * by the linker. MH_EXECUTE and MH_FVMLIB only. */
+#define SEG_LINKEDIT "__LINKEDIT"
+/** The unix stack segment. */
+#define SEG_UNIXSTACK "__UNIXSTACK"
+/** The segment for the self modifying code for dynamic linking.
+ * Implies RWX permissions. */
+#define SEG_IMPORT "__IMPORT"
+/** @} */
+
+
+/** @todo fvmlib */
+/** @todo fvmlib_command (LC_IDFVMLIB or LC_LOADFVMLIB) */
+/** @todo dylib */
+/** @todo dylib_command (LC_ID_DYLIB, LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB,
+ * LC_REEXPORT_DYLIB, LC_LAZY_LOAD_DYLIB) */
+/** @todo sub_framework_command (LC_SUB_FRAMEWORK) */
+/** @todo sub_client_command (LC_SUB_CLIENT) */
+/** @todo sub_umbrella_command (LC_SUB_UMBRELLA) */
+/** @todo sub_library_command (LC_SUB_LIBRARY) */
+/** @todo prebound_dylib_command (LC_PREBOUND_DYLIB) */
+/** @todo dylinker_command (LC_ID_DYLINKER or LC_LOAD_DYLINKER,
+ * LC_DYLD_ENVIRONMENT) */
+
+/**
+ * Thread command.
+ *
+ * State description of a thread that is to be created. The description
+ * is made up of a number of state structures preceded by a 32-bit flavor
+ * and 32-bit count field stating the kind of stat structure and it's size
+ * in KU32 items respecitvly.
+ *
+ * LC_UNIXTHREAD differs from LC_THREAD in that it implies stack creation
+ * and that it's started with the typical main(int, char **, char **) frame
+ * on the stack.
+ */
+typedef struct thread_command
+{
+ KU32 cmd; /**< LC_UNIXTHREAD or LC_THREAD. */
+ KU32 cmdsize; /**< The size of the command (including this header). */
+} thread_command_t;
+
+
+/** @todo routines_command (LC_ROUTINES) */
+/** @todo routines_command_64 (LC_ROUTINES_64) */
+
+
+/**
+ * Symbol table command.
+ * Contains a.out style symbol table with some tricks.
+ */
+typedef struct symtab_command
+{
+ KU32 cmd; /**< LC_SYMTAB */
+ KU32 cmdsize; /** sizeof(symtab_command_t) */
+ KU32 symoff; /** The file offset of the symbol table. */
+ KU32 nsyms; /** The number of symbols in the symbol table. */
+ KU32 stroff; /** The file offset of the string table. */
+ KU32 strsize; /** The size of the string table. */
+} symtab_command_t;
+
+
+/** @todo dysymtab_command (LC_DYSYMTAB) */
+/** @todo dylib_table_of_contents */
+/** @todo dylib_module_32 */
+/** @todo dylib_module_64 */
+/** @todo dylib_reference */
+/** @todo twolevel_hints_command (LC_TWOLEVEL_HINTS) */
+/** @todo twolevel_hint */
+/** @todo prebind_cksum_command (LC_PREBIND_CKSUM) */
+
+
+/**
+ * UUID generated by ld.
+ */
+typedef struct uuid_command
+{
+ KU32 cmd; /**< LC_UUID */
+ KU32 cmdsize; /**< sizeof(uuid_command_t) */
+ KU8 uuid[16]; /** The UUID bytes. */
+} uuid_command_t;
+
+
+/** @todo symseg_command (LC_SYMSEG) */
+/** @todo ident_command (LC_IDENT) */
+/** @todo fvmfile_command (LC_FVMFILE) */
+/** @todo rpath_command (LC_RPATH) */
+
+typedef struct linkedit_data_command
+{
+ KU32 cmd; /**< LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO, LC_FUNCTION_STARTS */
+ KU32 cmdsize; /**< size of this structure. */
+ KU32 dataoff; /**< Offset into the file of the data. */
+ KU32 datasize; /**< The size of the data. */
+} linkedit_data_command_t;
+
+/** @todo encryption_info_command (LC_ENCRYPTION_INFO) */
+/** @todo dyld_info_command (LC_DYLD_INFO, LC_DYLD_INFO_ONLY) */
+
+typedef struct version_min_command
+{
+ KU32 cmd; /**< LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS */
+ KU32 cmdsize; /**< size of this structure. */
+ KU32 version; /**< 31..16=major, 15..8=minor, 7..0=patch. */
+ KU32 reserved; /**< MBZ. */
+} version_min_command_t;
+
+/** @} */
+
+
+
+/** @defgroup grp_macho_o_syms Symbol Table
+ * @{ */
+
+/**
+ * The 32-bit Mach-O version of the nlist structure.
+ *
+ * This differs from the a.out nlist struct in that the unused n_other field
+ * was renamed to n_sect and used for keeping the relevant section number.
+ * @remark This structure is not name mach_nlist_32 in the Apple headers, but nlist.
+ */
+typedef struct macho_nlist_32
+{
+ union
+ {
+ KI32 n_strx; /**< Offset (index) into the string table. 0 means "". */
+ } n_un;
+ KU8 n_type; /**< Symbol type. */
+ KU8 n_sect; /**< Section number of NO_SECT. */
+ KI16 n_desc; /**< Type specific, debug info details mostly.*/
+ KU32 n_value; /**< The symbol value or stab offset. */
+} macho_nlist_32_t;
+
+
+/**
+ * The 64-bit Mach-O version of the nlist structure.
+ * @see macho_nlist_32
+ */
+typedef struct macho_nlist_64
+{
+ union
+ {
+ KU32 n_strx; /**< Offset (index) into the string table. 0 means "". */
+ } n_un;
+ KU8 n_type; /**< Symbol type. */
+ KU8 n_sect; /**< Section number of NO_SECT. */
+ KI16 n_desc; /**< Type specific, debug info details mostly.*/
+ KU64 n_value; /**< The symbol value or stab offset. */
+} macho_nlist_64_t;
+
+
+/** @name Symbol Type Constants (macho_nlist_32_t::n_type, macho_nlist_64_t::n_type)
+ *
+ * In the Mach-O world n_type is somewhat similar to a.out, meaning N_EXT, N_UNDF, N_ABS
+ * and the debug symbols are essentially the same, but the remaining stuff is different.
+ * The main reason for this is that the encoding of section has been moved to n_sect
+ * to permit up to 255 sections instead of the fixed 3 a.out sections (not counting
+ * the abs symbols and set vectors).
+ *
+ * To avoid confusion with a.out the Mach-O constants has been fitted with a MACHO_
+ * prefix here.
+ *
+ * Common symbols (aka communal symbols and comdefs) are represented by
+ * n_type = MACHO_N_EXT | MACHO_N_UNDF, n_sect = NO_SECT and n_value giving
+ * the size.
+ *
+ *
+ * Symbol table entries can be inserted directly in the assembly code using
+ * this notation:
+ * @code
+ * .stabs "n_name", n_type, n_sect, n_desc, n_value
+ * @endcode
+ *
+ * (1) The line number is optional, GCC doesn't set it.
+ * (2) The type is optional, GCC doesn't set it.
+ * (3) The binutil header is "skeptical" about the line. I'm skeptical about the whole thing... :-)
+ * (M) Mach-O specific?
+ * (S) Sun specific?
+ * @{
+ */
+
+/* Base masks. */
+#define MACHO_N_EXT KU8_C(0x01) /**< External symbol (when set) (N_EXT). */
+#define MACHO_N_TYPE KU8_C(0x0e) /**< Symbol type (N_TYPE without the 8th bit). */
+#define MACHO_N_PEXT KU8_C(0x10) /**< Private extern symbol (when set). (M) */
+#define MACHO_N_STAB KU8_C(0xe0) /**< Debug symbol mask (N_STAB). */
+
+/* MACHO_N_TYPE values. */
+#define MACHO_N_UNDF KU8_C(0x00) /**< MACHO_N_TYPE: Undefined symbol (N_UNDF). n_sect = NO_SECT. */
+#define MACHO_N_ABS KU8_C(0x02) /**< MACHO_N_TYPE: Absolute symbol (N_UNDF). n_sect = NO_SECT. */
+#define MACHO_N_INDR KU8_C(0x0a) /**< MACHO_N_TYPE: Indirect symbol, n_value is the index of the symbol. (M) */
+#define MACHO_N_PBUD KU8_C(0x0c) /**< MACHO_N_TYPE: Prebound undefined symbo (defined in a dylib). (M) */
+#define MACHO_N_SECT KU8_C(0x0e) /**< MACHO_N_TYPE: Defined in the section given by n_sects. (M) */
+
+/* Debug symbols. */
+#define MACHO_N_GSYM KU8_C(0x20) /**< Global variable. "name",, NO_SECT, type, 0 (2) */
+#define MACHO_N_FNAME KU8_C(0x22) /**< Function name (F77). "name",, NO_SECT, 0, 0 */
+#define MACHO_N_FUN KU8_C(0x24) /**< Function / text var. "name",, section, line, address (1) */
+#define MACHO_N_STSYM KU8_C(0x26) /**< Static data symbol. "name",, section, type, address (2) */
+#define MACHO_N_LCSYM KU8_C(0x28) /**< static bss symbol. "name",, section, type, address (2) */
+ /* omits N_MAIN and N_ROSYM. */
+#define MACHO_N_BNSYM KU8_C(0x2e) /**< Begin nsect symbol. 0,, section, 0, address (M) */
+#define MACHO_N_PC KU8_C(0x30) /**< Global pascal symbol. "name",, NO_SECT, subtype?, line (3) */
+ /* omits N_NSYMS, N_NOMAP and N_OBJ. */
+#define MACHO_N_OPT KU8_C(0x3c) /**< Options for the debugger related to the language of the
+ source file. "options?",,,, */
+#define MACHO_N_RSYM KU8_C(0x40) /**< Register variable. "name",, NO_SECT, type, register */
+ /* omits N_M2C */
+#define MACHO_N_SLINE KU8_C(0x44) /**< Source line. 0,, section, line, address */
+ /* omits N_DSLINE, N_BSLINE / N_BROWS, N_DEFD and N_FLINE. */
+#define MACHO_N_ENSYM KU8_C(0x4e) /**< End nsect symbol. 0,, section, 0, address (M) */
+ /* omits N_EHDECL / N_MOD2 and N_CATCH. */
+#define MACHO_N_SSYM KU8_C(0x60) /**< Struct/union element. "name",, NO_SECT, type, offset */
+ /* omits N_ENDM */
+#define MACHO_N_SO KU8_C(0x64) /**< Source file name. "fname",, section, 0, address */
+#define MACHO_N_OSO KU8_C(0x66) /**< Object file name. "fname",, 0, 0, st_mtime (M?) */
+ /* omits N_ALIAS */
+#define MACHO_N_LSYM KU8_C(0x80) /**< Stack variable. "name",, NO_SECT, type, frame_offset */
+#define MACHO_N_BINCL KU8_C(0x82) /**< Begin #include. "fname",, NO_SECT, 0, sum? */
+#define MACHO_N_SOL KU8_C(0x84) /**< #included file. "fname",, section, 0, start_address (S) */
+#define MACHO_N_PARAMS KU8_C(0x86) /**< Compiler params. "params",, NO_SECT, 0, 0 */
+#define MACHO_N_VERSION KU8_C(0x88) /**< Compiler version. "version",, NO_SECT, 0, 0 */
+#define MACHO_N_OLEVEL KU8_C(0x8A) /**< Compiler -O level. "level",, NO_SECT, 0, 0 */
+#define MACHO_N_PSYM KU8_C(0xa0) /**< Parameter variable. "name",, NO_SECT, type, frame_offset */
+#define MACHO_N_EINCL KU8_C(0xa2) /**< End #include. "fname",, NO_SECT, 0, 0 (S) */
+#define MACHO_N_ENTRY KU8_C(0xa4) /**< Alternate entry point. "name",, section, line, address */
+#define MACHO_N_LBRAC KU8_C(0xc0) /**< Left bracket. 0,, NO_SECT, nesting_level, address */
+#define MACHO_N_EXCL KU8_C(0xc2) /**< Deleted include file. "fname",, NO_SECT, 0, sum? (S) */
+ /* omits N_SCOPE */
+#define MACHO_N_RBRAC KU8_C(0xe0) /**< Right bracket. 0,, NO_SECT, nesting_level, address */
+#define MACHO_N_BCOMM KU8_C(0xe2) /**< Begin common. "name",, NO_SECT?, 0, 0 */
+#define MACHO_N_ECOMM KU8_C(0xe4) /**< End common. "name",, section, 0, 0 */
+#define MACHO_N_ECOML KU8_C(0xe8) /**< End local common. 0,, section, 0, address */
+#define MACHO_N_LENG KU8_C(0xfe) /**< Length-value of the preceding entry.
+ "name",, NO_SECT, 0, length */
+
+/** @} */
+
+/** @name Symbol Description Bits (macho_nlist_32_t::n_desc, macho_nlist_64_t::n_desc)
+ *
+ * Mach-O puts the n_desc field to a number of uses, like lazy binding , library
+ * ordinal numbers for -twolevel_namespace, stripping and weak symbol handling.
+ *
+ * @remark The REFERENCE_FLAGS_* are really not flags in the normal sense (bit),
+ * they are more like enum values.
+ * @{
+ */
+
+#define REFERENCE_TYPE KU16_C(0x000f) /**< The reference type mask. */
+#define REFERENCE_FLAG_UNDEFINED_NON_LAZY 0 /**< Normal undefined symbol. */
+#define REFERENCE_FLAG_UNDEFINED_LAZY 1 /**< Lazy undefined symbol. */
+#define REFERENCE_FLAG_DEFINED 2 /**< Defined symbol (dynamic linking). */
+#define REFERENCE_FLAG_PRIVATE_DEFINED 3 /**< Defined private symbol (dynamic linking). */
+#define REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY 4 /**< Normal undefined private symbol. */
+#define REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY 5 /**< Lazy undefined private symbol. */
+
+#define REFERENCED_DYNAMICALLY KU16_C(0x0010) /**< Don't strip. */
+
+
+/** Get the dynamic library ordinal. */
+#define GET_LIBRARY_ORDINAL(n_desc) \
+ (((n_desc) >> 8) & 0xff)
+/** Set the dynamic library ordinal. */
+#define SET_LIBRARY_ORDINAL(n_desc, ordinal) \
+ (n_desc) = (((n_desc) & 0xff) | (((ordinal) & 0xff) << 8))
+#define SELF_LIBRARY_ORDINAL 0x00 /**< Special ordinal for refering to onself. */
+#define MAX_LIBRARY_ORDINAL 0xfd /**< Maximum ordinal number. */
+#define DYNAMIC_LOOKUP_ORDINAL 0xfe /**< Special ordinal number for dynamic lookup. (Mac OS X 10.3 and later) */
+#define EXECUTABLE_ORDINAL 0xff /**< Special ordinal number for the executable. */
+
+
+/** Only MH_OBJECT: Never dead strip me! */
+#define N_NO_DEAD_STRIP KU16_C(0x0020)
+/** Not MH_OBJECT: Discarded symbol. */
+#define N_DESC_DISCARDED KU16_C(0x0020)
+/** Weak external symbol. Symbol can be missing, in which case it's will have the value 0. */
+#define N_WEAK_REF KU16_C(0x0040)
+/** Weak symbol definition. The symbol can be overridden by another weak
+ * symbol already present or by a non-weak (strong) symbol definition.
+ * Currently only supported for coalesed symbols.
+ * @remark This bit means something differently for undefined symbols, see N_REF_TO_WEAK.
+ */
+#define N_WEAK_DEF KU16_C(0x0080)
+/** Reference to a weak symbol, resolve using flat namespace searching.
+ * @remark This bit means something differently for defined symbols, see N_WEAK_DEF. */
+#define N_REF_TO_WEAK KU16_C(0x0080)
+
+/** @} */
+
+/** @} */
+
+
+/** @defgroup grp_macho_o_relocs Relocations
+ * @{ */
+
+/**
+ * Relocation entry.
+ *
+ * Differs from a.out in the meaning of r_symbolnum when r_extern=0 and
+ * that r_pad is made into r_type.
+ *
+ * @remark This structure and type has been prefixed with macho_ to avoid
+ * confusion with the original a.out type.
+ */
+typedef struct macho_relocation_info
+{
+ KI32 r_address; /**< Section relative address of the fixup.
+ The top bit (signed) indicates that this is a scattered
+ relocation if set, see scattered_relocation_info_t. */
+ KU32 r_symbolnum : 24, /**< r_extern=1: Symbol table index, relocate with the address of this symbol.
+ r_extern=0: Section ordinal, relocate with the address of this section. */
+ r_pcrel : 1, /**< PC (program counter) relative fixup; subtract the fixup address. */
+ r_length : 2, /**< Fixup length: 0=KU8, 1=KU16, 2=KU32, 3=KU64. */
+ r_extern : 1, /**< External or internal fixup, decides the r_symbolnum interpretation.. */
+ r_type : 4; /**< Relocation type; 0 is standard, non-zero are machine specific. */
+} macho_relocation_info_t;
+
+/** Special section ordinal value for absolute relocations. */
+#define R_ABS 0
+
+/** Flag in r_address indicating that the relocation is of the
+ * scattered_relocation_info_t kind and not macho_relocation_info_t. */
+#define R_SCATTERED KU32_C(0x80000000)
+
+/**
+ * Scattered relocation.
+ *
+ * This is a hack mainly for RISC machines which restricts section size
+ * to 16MB among other things.
+ *
+ * The reason for the big/little endian differences here is of course because
+ * of the R_SCATTERED mask and the way bitfields are implemented by the
+ * C/C++ compilers.
+ */
+typedef struct scattered_relocation_info
+{
+#if K_ENDIAN == K_ENDIAN_LITTLE
+ KU32 r_address : 24, /**< Section relative address of the fixup. (macho_relocation_info_t::r_address) */
+ r_type : 4, /**< Relocation type; 0 is standard, non-zero are machine specific. (macho_relocation_info_t::r_type) */
+ r_length : 2, /**< Fixup length: 0=KU8, 1=KU16, 2=KU32, 3=KU64. (macho_relocation_info_t::r_length) */
+ r_pcrel : 1, /**< PC (program counter) relative fixup; subtract the fixup address. (macho_relocation_info_t::r_pcrel) */
+ r_scattered : 1; /**< Set if scattered relocation, clear if normal relocation. */
+#elif K_ENDIAN == K_ENDIAN_BIG
+ KU32 r_scattered : 1, /**< Set if scattered relocation, clear if normal relocation. */
+ r_pcrel : 1, /**< PC (program counter) relative fixup; subtract the fixup address. (macho_relocation_info_t::r_pcrel) */
+ r_length : 2, /**< Fixup length: 0=KU8, 1=KU16, 2=KU32, 3=KU64. (macho_relocation_info_t::r_length) */
+ r_type : 4, /**< Relocation type; 0 is standard, non-zero are machine specific. (macho_relocation_info_t::r_type) */
+ r_address : 24; /**< Section relative address of the fixup. (macho_relocation_info_t::r_address) */
+#else
+# error "Neither K_ENDIAN isn't LITTLE or BIG!"
+#endif
+ KI32 r_value; /**< The value the fixup is refering to (without offset added). */
+} scattered_relocation_info_t;
+
+/**
+ * Relocation type values for a generic implementation (for r_type).
+ */
+typedef enum reloc_type_generic
+{
+ GENERIC_RELOC_VANILLA = 0, /**< Standard relocation. */
+ GENERIC_RELOC_PAIR, /**< Follows GENERIC_RELOC_SECTDIFF. */
+ GENERIC_RELOC_SECTDIFF, /**< ??? */
+ GENERIC_RELOC_PB_LA_PTR, /**< Prebound lazy pointer whatever that. */
+ GENERIC_RELOC_LOCAL_SECTDIFF /**< ??? */
+} reloc_type_generic_t;
+
+/**
+ * Relocation type values for AMD64 (for r_type).
+ */
+typedef enum reloc_type_x86_64
+{
+ X86_64_RELOC_UNSIGNED = 0, /**< Absolute address. */
+ X86_64_RELOC_SIGNED, /**< Signed displacement. */
+ X86_64_RELOC_BRANCH, /**< Branch displacement (jmp/call, adj by size). */
+ X86_64_RELOC_GOT_LOAD, /**< GOT entry load. */
+ X86_64_RELOC_GOT, /**< GOT reference. */
+ X86_64_RELOC_SUBTRACTOR, /**< ??. */
+ X86_64_RELOC_SIGNED_1, /**< Signed displacement with a -1 added. */
+ X86_64_RELOC_SIGNED_2, /**< Signed displacement with a -2 added. */
+ X86_64_RELOC_SIGNED_4 /**< Signed displacement with a -4 added. */
+} reloc_type_x86_64_t;
+
+/** @} */
+
+
+/** @} */
+#endif
+
diff --git a/src/lib/kStuff/include/k/kLdrFmts/mz.h b/src/lib/kStuff/include/k/kLdrFmts/mz.h
new file mode 100644
index 0000000..b159cac
--- /dev/null
+++ b/src/lib/kStuff/include/k/kLdrFmts/mz.h
@@ -0,0 +1,70 @@
+/* $Id: mz.h 31 2009-07-01 21:08:06Z bird $ */
+/** @file
+ * MZ structures, types and defines.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kLdrFmts_mz_h___
+#define ___k_kLdrFmts_mz_h___
+
+#include <k/kDefs.h>
+#include <k/kTypes.h>
+
+#pragma pack(1) /* not required */
+
+typedef struct _IMAGE_DOS_HEADER
+{
+ KU16 e_magic;
+ KU16 e_cblp;
+ KU16 e_cp;
+ KU16 e_crlc;
+ KU16 e_cparhdr;
+ KU16 e_minalloc;
+ KU16 e_maxalloc;
+ KU16 e_ss;
+ KU16 e_sp;
+ KU16 e_csum;
+ KU16 e_ip;
+ KU16 e_cs;
+ KU16 e_lfarlc;
+ KU16 e_ovno;
+ KU16 e_res[4];
+ KU16 e_oemid;
+ KU16 e_oeminfo;
+ KU16 e_res2[10];
+ KU32 e_lfanew;
+} IMAGE_DOS_HEADER;
+typedef IMAGE_DOS_HEADER *PIMAGE_DOS_HEADER;
+
+#ifndef IMAGE_DOS_SIGNATURE
+# define IMAGE_DOS_SIGNATURE K_LE2H_U16('M' | ('Z' << 8))
+#endif
+
+#pragma pack()
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kLdrFmts/pe.h b/src/lib/kStuff/include/k/kLdrFmts/pe.h
new file mode 100644
index 0000000..42af4df
--- /dev/null
+++ b/src/lib/kStuff/include/k/kLdrFmts/pe.h
@@ -0,0 +1,566 @@
+/* $Id: pe.h 92 2016-09-08 15:31:37Z bird $ */
+/** @file
+ * PE structures, types and defines.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kLdrFmts_pe_h___
+#define ___k_kLdrFmts_pe_h___
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include <k/kTypes.h>
+#include <k/kDefs.h>
+
+
+/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
+#ifndef IMAGE_NT_SIGNATURE
+# define IMAGE_NT_SIGNATURE K_LE2H_U32('P' | ('E' << 8))
+#endif
+
+/* file header */
+#define IMAGE_FILE_MACHINE_UNKNOWN 0x0000
+#define IMAGE_FILE_MACHINE_I386 0x014c
+#define IMAGE_FILE_MACHINE_AMD64 0x8664
+#define IMAGE_FILE_MACHINE_ARM 0x01c0
+#define IMAGE_FILE_MACHINE_ARMNT 0x01c4
+#define IMAGE_FILE_MACHINE_ARM64 0xaa64
+#define IMAGE_FILE_MACHINE_EBC 0x0ebc
+
+#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
+#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
+#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
+#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
+#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010
+#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020
+#define IMAGE_FILE_16BIT_MACHINE 0x0040
+#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
+#define IMAGE_FILE_32BIT_MACHINE 0x0100
+#define IMAGE_FILE_DEBUG_STRIPPED 0x0200
+#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400
+#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800
+#define IMAGE_FILE_SYSTEM 0x1000
+#define IMAGE_FILE_DLL 0x2000
+#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000
+#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
+
+/** Raw UUID byte for the ANON_OBJECT_HEADER_BIGOBJ::ClassID value.
+ * These make out {d1baa1c7-baee-4ba9-af20-faf66aa4dcb8}. */
+#define ANON_OBJECT_HEADER_BIGOBJ_CLS_ID_BYTES \
+ 0xc7, 0xa1, 0xba, 0xd1,/*-*/ 0xee, 0xba,/*-*/ 0xa9, 0x4b,/*-*/ 0xaf, 0x20,/*-*/ 0xfa, 0xf6, 0x6a, 0xa4, 0xdc, 0xb8
+
+/* optional header */
+#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10B
+#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20B
+
+#define IMAGE_SUBSYSTEM_UNKNOWN 0x0
+#define IMAGE_SUBSYSTEM_NATIVE 0x1
+#define IMAGE_SUBSYSTEM_WINDOWS_GUI 0x2
+#define IMAGE_SUBSYSTEM_WINDOWS_CUI 0x3
+#define IMAGE_SUBSYSTEM_OS2_GUI 0x4
+#define IMAGE_SUBSYSTEM_OS2_CUI 0x5
+#define IMAGE_SUBSYSTEM_POSIX_CUI 0x7
+
+#define IMAGE_LIBRARY_PROCESS_INIT 0x0001
+#define IMAGE_LIBRARY_PROCESS_TERM 0x0002
+#define IMAGE_LIBRARY_THREAD_INIT 0x0004
+#define IMAGE_LIBRARY_THREAD_TERM 0x0008
+#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 0x0200
+#define IMAGE_DLLCHARACTERISTICS_NO_SEH 0x0400
+#define IMAGE_DLLCHARACTERISTICS_NO_BIND 0x0800
+#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000
+#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
+
+#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 0x10
+
+#define IMAGE_DIRECTORY_ENTRY_EXPORT 0x0
+#define IMAGE_DIRECTORY_ENTRY_IMPORT 0x1
+#define IMAGE_DIRECTORY_ENTRY_RESOURCE 0x2
+#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 0x3
+#define IMAGE_DIRECTORY_ENTRY_SECURITY 0x4
+#define IMAGE_DIRECTORY_ENTRY_BASERELOC 0x5
+#define IMAGE_DIRECTORY_ENTRY_DEBUG 0x6
+#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 0x7
+#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT IMAGE_DIRECTORY_ENTRY_ARCHITECTURE
+#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 0x8
+#define IMAGE_DIRECTORY_ENTRY_TLS 0x9
+#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 0xa
+#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 0xb
+#define IMAGE_DIRECTORY_ENTRY_IAT 0xc
+#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 0xd
+#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 0xe
+
+
+/* section header */
+#define IMAGE_SIZEOF_SHORT_NAME 0x8
+
+#define IMAGE_SCN_TYPE_REG 0x00000000
+#define IMAGE_SCN_TYPE_DSECT 0x00000001
+#define IMAGE_SCN_TYPE_NOLOAD 0x00000002
+#define IMAGE_SCN_TYPE_GROUP 0x00000004
+#define IMAGE_SCN_TYPE_NO_PAD 0x00000008
+#define IMAGE_SCN_TYPE_COPY 0x00000010
+
+#define IMAGE_SCN_CNT_CODE 0x00000020
+#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
+
+#define IMAGE_SCN_LNK_OTHER 0x00000100
+#define IMAGE_SCN_LNK_INFO 0x00000200
+#define IMAGE_SCN_TYPE_OVER 0x00000400
+#define IMAGE_SCN_LNK_REMOVE 0x00000800
+#define IMAGE_SCN_LNK_COMDAT 0x00001000
+#define IMAGE_SCN_MEM_PROTECTED 0x00004000
+#define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000
+#define IMAGE_SCN_GPREL 0x00008000
+#define IMAGE_SCN_MEM_FARDATA 0x00008000
+#define IMAGE_SCN_MEM_SYSHEAP 0x00010000
+#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
+#define IMAGE_SCN_MEM_16BIT 0x00020000
+#define IMAGE_SCN_MEM_LOCKED 0x00040000
+#define IMAGE_SCN_MEM_PRELOAD 0x00080000
+
+#define IMAGE_SCN_ALIGN_1BYTES 0x00100000
+#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
+#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
+#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
+#define IMAGE_SCN_ALIGN_16BYTES 0x00500000
+#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
+#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
+#define IMAGE_SCN_ALIGN_128BYTES 0x00800000
+#define IMAGE_SCN_ALIGN_256BYTES 0x00900000
+#define IMAGE_SCN_ALIGN_512BYTES 0x00A00000
+#define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000
+#define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000
+#define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000
+#define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000
+#define IMAGE_SCN_ALIGN_MASK 0x00F00000
+
+#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
+#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000
+#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000
+#define IMAGE_SCN_MEM_SHARED 0x10000000
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000
+#define IMAGE_SCN_MEM_READ 0x40000000
+#define IMAGE_SCN_MEM_WRITE 0x80000000
+
+
+/* relocations */
+#define IMAGE_REL_BASED_ABSOLUTE 0x0
+#define IMAGE_REL_BASED_HIGH 0x1
+#define IMAGE_REL_BASED_LOW 0x2
+#define IMAGE_REL_BASED_HIGHLOW 0x3
+#define IMAGE_REL_BASED_HIGHADJ 0x4
+#define IMAGE_REL_BASED_MIPS_JMPADDR 0x5
+#define IMAGE_REL_BASED_SECTION 0x6
+#define IMAGE_REL_BASED_REL32 0x7
+/*#define IMAGE_REL_BASED_RESERVED1 0x8 */
+#define IMAGE_REL_BASED_MIPS_JMPADDR16 0x9
+#define IMAGE_REL_BASED_IA64_IMM64 0x9
+#define IMAGE_REL_BASED_DIR64 0xa
+#define IMAGE_REL_BASED_HIGH3ADJ 0xb
+
+/* imports */
+#define IMAGE_ORDINAL_FLAG32 0x80000000
+#define IMAGE_ORDINAL32(ord) ((ord) & 0xffff)
+#define IMAGE_SNAP_BY_ORDINAL32(ord) (!!((ord) & IMAGE_ORDINAL_FLAG32))
+
+#define IMAGE_ORDINAL_FLAG64 0x8000000000000000ULL
+#define IMAGE_ORDINAL64(ord) ((ord) & 0xffff)
+#define IMAGE_SNAP_BY_ORDINAL64(ord) (!!((ord) & IMAGE_ORDINAL_FLAG64))
+
+
+/* dll/tls entry points argument */
+#define DLL_PROCESS_DETACH 0
+#define DLL_PROCESS_ATTACH 1
+#define DLL_THREAD_ATTACH 2
+#define DLL_THREAD_DETACH 3
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+#pragma pack(4)
+
+typedef struct _IMAGE_FILE_HEADER
+{
+ KU16 Machine;
+ KU16 NumberOfSections;
+ KU32 TimeDateStamp;
+ KU32 PointerToSymbolTable;
+ KU32 NumberOfSymbols;
+ KU16 SizeOfOptionalHeader;
+ KU16 Characteristics;
+} IMAGE_FILE_HEADER;
+typedef IMAGE_FILE_HEADER *PIMAGE_FILE_HEADER;
+
+
+typedef struct _ANON_OBJECT_HEADER
+{
+ KU16 Sig1;
+ KU16 Sig2;
+ KU16 Version; /**< >= 1 */
+ KU16 Machine;
+ KU32 TimeDataStamp;
+ KU8 ClassID[16];
+ KU32 SizeOfData;
+} ANON_OBJECT_HEADER;
+typedef ANON_OBJECT_HEADER *PANON_OBJECT_HEADER;
+
+
+typedef struct _ANON_OBJECT_HEADER_V2
+{
+ KU16 Sig1;
+ KU16 Sig2;
+ KU16 Version; /**< >= 2 */
+ KU16 Machine;
+ KU32 TimeDataStamp;
+ KU8 ClassID[16];
+ KU32 SizeOfData;
+ /* New fields for Version >= 2: */
+ KU32 Flags;
+ KU32 MetaDataSize; /**< CLR metadata */
+ KU32 MetaDataOffset;
+} ANON_OBJECT_HEADER_V2;
+typedef ANON_OBJECT_HEADER_V2 *PANON_OBJECT_HEADER_V2;
+
+
+typedef struct _ANON_OBJECT_HEADER_BIGOBJ
+{
+ KU16 Sig1;
+ KU16 Sig2;
+ KU16 Version; /**< >= 2 */
+ KU16 Machine;
+ KU32 TimeDataStamp;
+ KU8 ClassID[16]; /**< ANON_OBJECT_HEADER_BIGOBJ_CLS_ID_BYTES */
+ KU32 SizeOfData;
+ /* New fields for Version >= 2: */
+ KU32 Flags;
+ KU32 MetaDataSize; /**< CLR metadata */
+ KU32 MetaDataOffset;
+ /* Specific for bigobj: */
+ KU32 NumberOfSections;
+ KU32 PointerToSymbolTable;
+ KU32 NumberOfSymbols;
+} ANON_OBJECT_HEADER_BIGOBJ;
+typedef ANON_OBJECT_HEADER_BIGOBJ *PANON_OBJECT_HEADER_BIGOBJ;
+
+
+typedef struct _IMAGE_DATA_DIRECTORY
+{
+ KU32 VirtualAddress;
+ KU32 Size;
+} IMAGE_DATA_DIRECTORY;
+typedef IMAGE_DATA_DIRECTORY *PIMAGE_DATA_DIRECTORY;
+
+
+typedef struct _IMAGE_OPTIONAL_HEADER32
+{
+ KU16 Magic;
+ KU8 MajorLinkerVersion;
+ KU8 MinorLinkerVersion;
+ KU32 SizeOfCode;
+ KU32 SizeOfInitializedData;
+ KU32 SizeOfUninitializedData;
+ KU32 AddressOfEntryPoint;
+ KU32 BaseOfCode;
+ KU32 BaseOfData;
+ KU32 ImageBase;
+ KU32 SectionAlignment;
+ KU32 FileAlignment;
+ KU16 MajorOperatingSystemVersion;
+ KU16 MinorOperatingSystemVersion;
+ KU16 MajorImageVersion;
+ KU16 MinorImageVersion;
+ KU16 MajorSubsystemVersion;
+ KU16 MinorSubsystemVersion;
+ KU32 Win32VersionValue;
+ KU32 SizeOfImage;
+ KU32 SizeOfHeaders;
+ KU32 CheckSum;
+ KU16 Subsystem;
+ KU16 DllCharacteristics;
+ KU32 SizeOfStackReserve;
+ KU32 SizeOfStackCommit;
+ KU32 SizeOfHeapReserve;
+ KU32 SizeOfHeapCommit;
+ KU32 LoaderFlags;
+ KU32 NumberOfRvaAndSizes;
+ IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
+} IMAGE_OPTIONAL_HEADER32;
+typedef IMAGE_OPTIONAL_HEADER32 *PIMAGE_OPTIONAL_HEADER32;
+
+typedef struct _IMAGE_OPTIONAL_HEADER64
+{
+ KU16 Magic;
+ KU8 MajorLinkerVersion;
+ KU8 MinorLinkerVersion;
+ KU32 SizeOfCode;
+ KU32 SizeOfInitializedData;
+ KU32 SizeOfUninitializedData;
+ KU32 AddressOfEntryPoint;
+ KU32 BaseOfCode;
+ KU64 ImageBase;
+ KU32 SectionAlignment;
+ KU32 FileAlignment;
+ KU16 MajorOperatingSystemVersion;
+ KU16 MinorOperatingSystemVersion;
+ KU16 MajorImageVersion;
+ KU16 MinorImageVersion;
+ KU16 MajorSubsystemVersion;
+ KU16 MinorSubsystemVersion;
+ KU32 Win32VersionValue;
+ KU32 SizeOfImage;
+ KU32 SizeOfHeaders;
+ KU32 CheckSum;
+ KU16 Subsystem;
+ KU16 DllCharacteristics;
+ KU64 SizeOfStackReserve;
+ KU64 SizeOfStackCommit;
+ KU64 SizeOfHeapReserve;
+ KU64 SizeOfHeapCommit;
+ KU32 LoaderFlags;
+ KU32 NumberOfRvaAndSizes;
+ IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
+} IMAGE_OPTIONAL_HEADER64;
+typedef IMAGE_OPTIONAL_HEADER64 *PIMAGE_OPTIONAL_HEADER64;
+
+
+typedef struct _IMAGE_NT_HEADERS
+{
+ KU32 Signature;
+ IMAGE_FILE_HEADER FileHeader;
+ IMAGE_OPTIONAL_HEADER32 OptionalHeader;
+} IMAGE_NT_HEADERS32;
+typedef IMAGE_NT_HEADERS32 *PIMAGE_NT_HEADERS32;
+
+typedef struct _IMAGE_NT_HEADERS64
+{
+ KU32 Signature;
+ IMAGE_FILE_HEADER FileHeader;
+ IMAGE_OPTIONAL_HEADER64 OptionalHeader;
+} IMAGE_NT_HEADERS64;
+typedef IMAGE_NT_HEADERS64 *PIMAGE_NT_HEADERS64;
+
+
+typedef struct _IMAGE_SECTION_HEADER
+{
+ KU8 Name[IMAGE_SIZEOF_SHORT_NAME];
+ union
+ {
+ KU32 PhysicalAddress;
+ KU32 VirtualSize;
+ } Misc;
+ KU32 VirtualAddress;
+ KU32 SizeOfRawData;
+ KU32 PointerToRawData;
+ KU32 PointerToRelocations;
+ KU32 PointerToLinenumbers;
+ KU16 NumberOfRelocations;
+ KU16 NumberOfLinenumbers;
+ KU32 Characteristics;
+} IMAGE_SECTION_HEADER;
+typedef IMAGE_SECTION_HEADER *PIMAGE_SECTION_HEADER;
+
+
+typedef struct _IMAGE_BASE_RELOCATION
+{
+ KU32 VirtualAddress;
+ KU32 SizeOfBlock;
+} IMAGE_BASE_RELOCATION;
+typedef IMAGE_BASE_RELOCATION *PIMAGE_BASE_RELOCATION;
+
+
+typedef struct _IMAGE_EXPORT_DIRECTORY
+{
+ KU32 Characteristics;
+ KU32 TimeDateStamp;
+ KU16 MajorVersion;
+ KU16 MinorVersion;
+ KU32 Name;
+ KU32 Base;
+ KU32 NumberOfFunctions;
+ KU32 NumberOfNames;
+ KU32 AddressOfFunctions;
+ KU32 AddressOfNames;
+ KU32 AddressOfNameOrdinals;
+} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
+
+
+typedef struct _IMAGE_IMPORT_DESCRIPTOR
+{
+ union
+ {
+ KU32 Characteristics;
+ KU32 OriginalFirstThunk;
+ } u;
+ KU32 TimeDateStamp;
+ KU32 ForwarderChain;
+ KU32 Name;
+ KU32 FirstThunk;
+} IMAGE_IMPORT_DESCRIPTOR;
+typedef IMAGE_IMPORT_DESCRIPTOR *PIMAGE_IMPORT_DESCRIPTOR;
+
+
+typedef struct _IMAGE_IMPORT_BY_NAME
+{
+ KU16 Hint;
+ KU8 Name[1];
+} IMAGE_IMPORT_BY_NAME;
+typedef IMAGE_IMPORT_BY_NAME *PIMAGE_IMPORT_BY_NAME;
+
+
+/* The image_thunk_data32/64 structures are not very helpful except for getting RSI. keep them around till all the code has been converted. */
+typedef struct _IMAGE_THUNK_DATA64
+{
+ union
+ {
+ KU64 ForwarderString;
+ KU64 Function;
+ KU64 Ordinal;
+ KU64 AddressOfData;
+ } u1;
+} IMAGE_THUNK_DATA64;
+typedef IMAGE_THUNK_DATA64 *PIMAGE_THUNK_DATA64;
+
+typedef struct _IMAGE_THUNK_DATA32
+{
+ union
+ {
+ KU32 ForwarderString;
+ KU32 Function;
+ KU32 Ordinal;
+ KU32 AddressOfData;
+ } u1;
+} IMAGE_THUNK_DATA32;
+typedef IMAGE_THUNK_DATA32 *PIMAGE_THUNK_DATA32;
+
+
+typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32
+{
+ KU32 Size;
+ KU32 TimeDateStamp;
+ KU16 MajorVersion;
+ KU16 MinorVersion;
+ KU32 GlobalFlagsClear;
+ KU32 GlobalFlagsSet;
+ KU32 CriticalSectionDefaultTimeout;
+ KU32 DeCommitFreeBlockThreshold;
+ KU32 DeCommitTotalFreeThreshold;
+ KU32 LockPrefixTable;
+ KU32 MaximumAllocationSize;
+ KU32 VirtualMemoryThreshold;
+ KU32 ProcessHeapFlags;
+ KU32 ProcessAffinityMask;
+ KU16 CSDVersion;
+ KU16 Reserved1;
+ KU32 EditList;
+ KU32 SecurityCookie;
+ KU32 SEHandlerTable;
+ KU32 SEHandlerCount;
+} IMAGE_LOAD_CONFIG_DIRECTORY32;
+typedef IMAGE_LOAD_CONFIG_DIRECTORY32 PIMAGE_LOAD_CONFIG_DIRECTORY32;
+
+typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64
+{
+ KU32 Size;
+ KU32 TimeDateStamp;
+ KU16 MajorVersion;
+ KU16 MinorVersion;
+ KU32 GlobalFlagsClear;
+ KU32 GlobalFlagsSet;
+ KU32 CriticalSectionDefaultTimeout;
+ KU64 DeCommitFreeBlockThreshold;
+ KU64 DeCommitTotalFreeThreshold;
+ KU64 LockPrefixTable;
+ KU64 MaximumAllocationSize;
+ KU64 VirtualMemoryThreshold;
+ KU64 ProcessAffinityMask;
+ KU32 ProcessHeapFlags;
+ KU16 CSDVersion;
+ KU16 Reserved1;
+ KU64 EditList;
+ KU64 SecurityCookie;
+ KU64 SEHandlerTable;
+ KU64 SEHandlerCount;
+} IMAGE_LOAD_CONFIG_DIRECTORY64;
+typedef IMAGE_LOAD_CONFIG_DIRECTORY64 *PIMAGE_LOAD_CONFIG_DIRECTORY64;
+
+typedef struct _IMAGE_DEBUG_DIRECTORY
+{
+ KU32 Characteristics;
+ KU32 TimeDateStamp;
+ KU16 MajorVersion;
+ KU16 MinorVersion;
+ KU32 Type;
+ KU32 SizeOfData;
+ KU32 AddressOfRawData;
+ KU32 PointerToRawData;
+} IMAGE_DEBUG_DIRECTORY;
+typedef IMAGE_DEBUG_DIRECTORY *PIMAGE_DEBUG_DIRECTORY;
+
+#define IMAGE_DEBUG_TYPE_UNKNOWN 0
+#define IMAGE_DEBUG_TYPE_COFF 1
+#define IMAGE_DEBUG_TYPE_CODEVIEW 2 /* 4.0 */
+#define IMAGE_DEBUG_TYPE_FPO 3 /* FPO = frame pointer omission */
+#define IMAGE_DEBUG_TYPE_MISC 4
+#define IMAGE_DEBUG_TYPE_EXCEPTION 5
+#define IMAGE_DEBUG_TYPE_FIXUP 6
+#define IMAGE_DEBUG_TYPE_BORLAND 9
+
+typedef struct _IMAGE_TLS_DIRECTORY32
+{
+ KU32 StartAddressOfRawData;
+ KU32 EndAddressOfRawData;
+ KU32 AddressOfIndex;
+ KU32 AddressOfCallBacks;
+ KU32 SizeOfZeroFill;
+ KU32 Characteristics;
+} IMAGE_TLS_DIRECTORY32;
+typedef IMAGE_TLS_DIRECTORY32 *PIMAGE_TLS_DIRECTORY32;
+
+typedef struct _IMAGE_TLS_DIRECTORY64
+{
+ KU64 StartAddressOfRawData;
+ KU64 EndAddressOfRawData;
+ KU64 AddressOfIndex;
+ KU64 AddressOfCallBacks;
+ KU32 SizeOfZeroFill;
+ KU32 Characteristics;
+} IMAGE_TLS_DIRECTORY64;
+typedef IMAGE_TLS_DIRECTORY64 *PIMAGE_TLS_DIRECTORY64;
+
+
+#pragma pack()
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kMagics.h b/src/lib/kStuff/include/k/kMagics.h
new file mode 100644
index 0000000..9690b9b
--- /dev/null
+++ b/src/lib/kStuff/include/k/kMagics.h
@@ -0,0 +1,43 @@
+/* $Id: kMagics.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kMagics - Various Magic Constants.
+ */
+
+/*
+ * 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.
+ */
+
+
+#ifndef ___k_kMagics_h___
+#define ___k_kMagics_h___
+
+/** The magic for KRDR::u32Magic. (Katsu Aki (Katsuaki Nakamura))
+ * @ingroup grp_kRdrAll */
+#define KRDR_MAGIC 0x19610919
+/** The magic value for the debug module structure. (Some manga artist)
+ * @ingroup grp_kDbgAll */
+#define KDBGMOD_MAGIC 0x19200501
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kRbTmpl/kRbAssert.h b/src/lib/kStuff/include/k/kRbTmpl/kRbAssert.h
new file mode 100644
index 0000000..03c17a4
--- /dev/null
+++ b/src/lib/kStuff/include/k/kRbTmpl/kRbAssert.h
@@ -0,0 +1,136 @@
+/* $Id: kRbAssert.h 38 2009-11-10 00:01:38Z bird $ */
+/** @file
+ * kRbTmpl - Templated Red-Black Trees, Assert Valid Tree.
+ */
+
+/*
+ * Copyright (c) 2009 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.
+ */
+
+
+/**
+ * Internal helper for KRB_FN(Assert)
+ *
+ * @returns The number of black nodes. -1 is return if the tree is invalid.
+ * @param pRoot The root of the (sub-)tree to assert.
+ */
+K_DECL_INLINE(int) KRB_FN(AssertRecurse)(KRBNODE *pRoot)
+{
+ int cLeft;
+ int cRight;
+
+ if (!pRoot)
+ /* leafs are black. */
+ return 1;
+
+#ifdef KRB_EQUAL_ALLOWED
+ /* equal nodes are equal :) */
+ if (pNode->mpList != KRB_NULL)
+ {
+ KRBROOT *pEqual;
+ for (pEqual = KRB_GET_POINTER(&pNode->mpList); pEqual; pEqual = KRB_GET_POINTER_NULL(&pEqual->mpList))
+ kHlpAssertReturn(K_CMP_E(pEqual->mKey, pNode->mKey), -1);
+ }
+#endif
+
+ /* binary tree. */
+ kHlpAssertReturn(pRoot->mpLeft != KRB_NULL && KRB_CMP_G(KRB_GET_POINTER(&pRoot->mpLeft)->mpKey, pRoot->mKey), -1);
+ kHlpAssertReturn(pRoot->mpRight != KRB_NULL && KRB_CMP_G(pRoot->mKey, KRB_GET_POINTER(&pRoot->mpRigth)->mpKey), -1);
+
+ /* both children of red nodes are black. */
+ kHlpAssertReturn(!KRB_IS_RED(pRoot) || (!KRB_IS_RED(pRoot->mpLeft) && !KRB_IS_RED(pRoot->mpRight)), -1);
+
+ /* all paths to leafs contains the same number of black nodes. */
+ cLeft = KRB_FN(AssertRecurse)(KRB_GET_POINTER_NULL(&pRoot->mpLeft));
+ cRight = KRB_FN(AssertRecurse)(KRB_GET_POINTER_NULL(&pRoot->mpRight));
+ kHlpAssertMsgReturn(cLeft == cRight || cLeft == -1 || cRight == -1, ("%d vs. %d\n", cLeft, cRight), -1);
+
+ return cLeft + !KRB_IS_RED(pRoot);
+}
+
+
+/**
+ * Asserts the validity of the Red-Black tree.
+ *
+ * This method is using recursion and may therefore consume quite a bit of stack
+ * on a large tree.
+ *
+ * @returns K_TRUE if valid.
+ * @returns K_FALSE if invalid, assertion raised on each violation.
+ * @param pRoot Pointer to the Red-Back tree's root structure.
+ */
+KRB_DECL(KBOOL) KRB_FN(Assert)(KRBROOT *pRoot)
+{
+ KBOOL fRc = K_TRUE;
+#ifdef KRB_CACHE_SIZE
+ unsigned i;
+#endif
+ KRBNODE *pNode;
+
+ KRB_READ_LOCK(pRoot);
+ if (pRoot->mpRoot == KRB_NULL)
+ {
+ KRB_READ_UNLOCK(pRoot);
+ return 0;
+ }
+
+#ifdef KRB_CACHE_SIZE
+ /*
+ * Validate the cache.
+ */
+ for (i = 0; i < (KRB_CACHE_SIZE); i++)
+ if (pRoot->maLookthru[i] != KRB_NULL)
+ {
+ KRBNODE pCache = KRB_GET_POINTER(&pRoot->maLookthru[i]);
+
+ /** @todo ranges */
+ kHlpAssertMsgStmt(i == KRB_CACHE_HASH(pCache->Key), ("Invalid cache entry %u, hashed to %u\n", i, KRB_CACHE_HASH(pCache->Key)), fRc = K_FALSE);
+
+ pNode = KRB_GET_POINTER(&pRoot->mpRoot);
+ while (pNode)
+ {
+ if (KRB_CMP_E(pCache->mKey, pNode->mKey))
+ {
+ kHlpAssertMsgStmt(pNode == pCache, ("Invalid cache entry %u=%p, found %p\n", i, pCache, pNode), fRc = K_FALSE);
+ break;
+ }
+ if (KRB_CMP_G(pCache->mKey, pNode->mKey))
+ pNode = KRB_GET_POINTER_NULL(&pNode->mRight);
+ else
+ pNode = KRB_GET_POINTER_NULL(&pNode->mLeft);
+ }
+ kHlpAssertMsgStmt(pNode, ("Invalid cache entry %u/%p - not found\n", i, pCache), fRc = K_FALSE);
+ }
+#endif
+
+ /*
+ * Recurse thru the tree.
+ */
+ if (KRB_FN(AssertRecurse)(KRB_GET_POINTER(&pRoot->mpRoot)) == -1)
+ fRc = K_FALSE;
+
+ KRB_READ_UNLOCK(pRoot);
+ return fRc;
+}
+
diff --git a/src/lib/kStuff/include/k/kRbTmpl/kRbBase.h b/src/lib/kStuff/include/k/kRbTmpl/kRbBase.h
new file mode 100644
index 0000000..c79f7ce
--- /dev/null
+++ b/src/lib/kStuff/include/k/kRbTmpl/kRbBase.h
@@ -0,0 +1,609 @@
+/* $Id: kRbBase.h 38 2009-11-10 00:01:38Z bird $ */
+/** @file
+ * kRbTmpl - Templated Red-Black Trees, The Mandatory Base Code.
+ */
+
+/*
+ * Copyright (c) 2001-2009 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.
+ */
+
+/** @page pg_kAvlTmpl Template Configuration.
+ *
+ * This is a templated implementation of Red-Black trees in C. The template
+ * parameters relates to the kind of key used and how duplicates are treated.
+ *
+ * \#define KRB_EQUAL_ALLOWED
+ * Define this to tell us that equal keys are allowed.
+ * Then Equal keys will be put in a list pointed to by KRBNODE::pList.
+ * This is by default not defined.
+ *
+ * \#define KRB_CHECK_FOR_EQUAL_INSERT
+ * Define this to enable insert check for equal nodes.
+ * This is by default not defined.
+ *
+ * \#define KRB_MAX_STACK
+ * Use this to specify the max number of stack entries the stack will use when
+ * inserting and removing nodes from the tree. The size should be something like
+ * log2(<max nodes>) + 3
+ * Must be defined.
+ *
+ * \#define KRB_RANGE
+ * Define this to enable key ranges.
+ *
+ * \#define KRB_OFFSET
+ * Define this to link the tree together using self relative offset
+ * instead of memory pointers, thus making the entire tree relocatable
+ * provided all the nodes - including the root node variable - are moved
+ * the exact same distance.
+ *
+ * \#define KRB_CACHE_SIZE
+ * Define this to employ a lookthru cache (direct) to speed up lookup for
+ * some usage patterns. The value should be the number of members of the array.
+ *
+ * \#define KRB_CACHE_HASH(Key)
+ * Define this to specify a more efficient translation of the key into
+ * a lookthru array index. The default is key % size.
+ * For some key types this is required as the default will not compile.
+ *
+ * \#define KRB_LOCKED
+ * Define this if you wish for the tree to be locked via the
+ * KRB_WRITE_LOCK, KRB_WRITE_UNLOCK, KRB_READ_LOCK and
+ * KRB_READ_UNLOCK macros. If not defined the tree will not be subject
+ * do any kind of locking and the problem of concurrency is left the user.
+ *
+ * \#define KRB_WRITE_LOCK(pRoot)
+ * Lock the tree for writing.
+ *
+ * \#define KRB_WRITE_UNLOCK(pRoot)
+ * Counteracts KRB_WRITE_LOCK.
+ *
+ * \#define KRB_READ_LOCK(pRoot)
+ * Lock the tree for reading.
+ *
+ * \#define KRB_READ_UNLOCK(pRoot)
+ * Counteracts KRB_READ_LOCK.
+ *
+ * \#define KRBKEY
+ * Define this to the name of the AVL key type.
+ *
+ * \#define KRB_STD_KEY_COMP
+ * Define this to use the standard key compare macros. If not set all the
+ * compare operations for KRBKEY have to be defined: KRB_CMP_G, KRB_CMP_E, KRB_CMP_NE,
+ * KRB_R_IS_IDENTICAL, KRB_R_IS_INTERSECTING and KRB_R_IS_IN_RANGE. The
+ * latter three are only required when KRB_RANGE is defined.
+ *
+ * \#define KRBNODE
+ * Define this to the name (typedef) of the AVL node structure. This
+ * structure must have a mpLeft, mpRight, mKey and mHeight member.
+ * If KRB_RANGE is defined a mKeyLast is also required.
+ * If KRB_EQUAL_ALLOWED is defined a mpList member is required.
+ * It's possible to use other member names by redefining the names.
+ *
+ * \#define KRBTREEPTR
+ * Define this to the name (typedef) of the tree pointer type. This is
+ * required when KRB_OFFSET is defined. When not defined it defaults
+ * to KRBNODE *.
+ *
+ * \#define KRBROOT
+ * Define this to the name (typedef) of the AVL root structure. This
+ * is optional. However, if specified it must at least have a mpRoot
+ * member of KRBTREEPTR type. If KRB_CACHE_SIZE is non-zero a
+ * maLookthru[KRB_CACHE_SIZE] member of the KRBTREEPTR type is also
+ * required.
+ *
+ * \#define KRB_FN
+ * Use this to alter the names of the AVL functions.
+ * Must be defined.
+ *
+ * \#define KRB_TYPE(prefix, name)
+ * Use this to make external type names and unique. The prefix may be empty.
+ * Must be defined.
+ *
+ * \#define KRB_INT(name)
+ * Use this to make internal type names and unique. The prefix may be empty.
+ * Must be defined.
+ *
+ * \#define KRB_DECL(rettype)
+ * Function declaration macro that should be set according to the scope
+ * the instantiated template should have. For instance an inlined scope
+ * (private or public) should K_DECL_INLINE(rettype) here.
+ *
+ * This version of the kAVL tree offers the option of inlining the entire
+ * implementation. This depends on the compiler doing a decent job in both
+ * making use of the inlined code and to eliminate const variables.
+ */
+
+
+/*******************************************************************************
+* Internal Functions *
+*******************************************************************************/
+#include <k/kDefs.h>
+#include <k/kTypes.h>
+#include <k/kHlpAssert.h>
+
+
+/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
+/** @def KRB_GET_POINTER
+ * Reads a 'pointer' value.
+ *
+ * @returns The native pointer.
+ * @param pp Pointer to the pointer to read.
+ * @internal
+ */
+
+/** @def KRB_GET_POINTER_NULL
+ * Reads a 'pointer' value which can be KRB_NULL.
+ *
+ * @returns The native pointer.
+ * @returns NULL pointer if KRB_NULL.
+ * @param pp Pointer to the pointer to read.
+ * @internal
+ */
+
+/** @def KRB_SET_POINTER
+ * Writes a 'pointer' value.
+ * For offset-based schemes offset relative to pp is calculated and assigned to *pp.
+ *
+ * @returns stored pointer.
+ * @param pp Pointer to where to store the pointer.
+ * @param p Native pointer to assign to *pp.
+ * @internal
+ */
+
+/** @def KRB_SET_POINTER_NULL
+ * Writes a 'pointer' value which can be KRB_NULL.
+ *
+ * For offset-based schemes offset relative to pp is calculated and assigned to *pp,
+ * if p is not KRB_NULL of course.
+ *
+ * @returns stored pointer.
+ * @param pp Pointer to where to store the pointer.
+ * @param pp2 Pointer to where to pointer to assign to pp. This can be KRB_NULL
+ * @internal
+ */
+
+#ifndef KRBTREEPTR
+# define KRBTREEPTR KRBNODE *
+#endif
+
+#ifndef KRBROOT
+# define KRBROOT KRB_TYPE(,ROOT)
+# define KRB_NEED_KRBROOT
+#endif
+
+#ifdef KRB_CACHE_SIZE
+# ifndef KRB_CACHE_HASH
+# define KRB_CACHE_HASH(Key) ( (Key) % (KRB_CACHE_SIZE) )
+# endif
+#elif defined(KRB_CACHE_HASH)
+# error "KRB_CACHE_HASH without KRB_CACHE_SIZE!"
+#endif
+
+#ifdef KRB_CACHE_SIZE
+# define KRB_CACHE_INVALIDATE_NODE(pRoot, pNode, Key) \
+ do { \
+ KRBTREEPTR **ppEntry = &pRoot->maLookthru[KRB_CACHE_HASH(Key)]; \
+ if ((pNode) == KRB_GET_POINTER_NULL(ppEntry)) \
+ *ppEntry = KRB_NULL; \
+ } while (0)
+#else
+# define KRB_CACHE_INVALIDATE_NODE(pRoot, pNode, Key) do { } while (0)
+#endif
+
+#ifndef KRB_LOCKED
+# define KRB_WRITE_LOCK(pRoot) do { } while (0)
+# define KRB_WRITE_UNLOCK(pRoot) do { } while (0)
+# define KRB_READ_LOCK(pRoot) do { } while (0)
+# define KRB_READ_UNLOCK(pRoot) do { } while (0)
+#endif
+
+#ifdef KRB_OFFSET
+# define KRB_GET_POINTER(pp) ( (KRBNODE *)((KIPTR)(pp) + *(pp)) )
+# define KRB_GET_POINTER_NULL(pp) ( *(pp) != KRB_NULL ? KRB_GET_POINTER(pp) : NULL )
+# define KRB_SET_POINTER(pp, p) ( (*(pp)) = ((KIPTR)(p) - (KIPTR)(pp)) )
+# define KRB_SET_POINTER_NULL(pp, pp2) ( (*(pp)) = *(pp2) != KRB_NULL ? (KIPTR)KRB_GET_POINTER(pp2) - (KIPTR)(pp) : KRB_NULL )
+#else
+# define KRB_GET_POINTER(pp) ( *(pp) )
+# define KRB_GET_POINTER_NULL(pp) ( *(pp) )
+# define KRB_SET_POINTER(pp, p) ( (*(pp)) = (p) )
+# define KRB_SET_POINTER_NULL(pp, pp2) ( (*(pp)) = *(pp2) )
+#endif
+
+
+/** @def KRB_NULL
+ * The NULL 'pointer' equivalent.
+ */
+#ifdef KRB_OFFSET
+# define KRB_NULL 0
+#else
+# define KRB_NULL NULL
+#endif
+
+#ifdef KRB_STD_KEY_COMP
+# define KRB_CMP_G(key1, key2) ( (key1) > (key2) )
+# define KRB_CMP_E(key1, key2) ( (key1) == (key2) )
+# define KRB_CMP_NE(key1, key2) ( (key1) != (key2) )
+# ifdef KRB_RANGE
+# define KRB_R_IS_IDENTICAL(key1B, key2B, key1E, key2E) ( (key1B) == (key2B) && (key1E) == (key2E) )
+# define KRB_R_IS_INTERSECTING(key1B, key2B, key1E, key2E) ( (key1B) <= (key2E) && (key1E) >= (key2B) )
+# define KRB_R_IS_IN_RANGE(key1B, key1E, key2) KRB_R_IS_INTERSECTING(key1B, key2, key1E, key2)
+# endif
+#endif
+
+#ifndef KRB_RANGE
+# define KRB_R_IS_INTERSECTING(key1B, key2B, key1E, key2E) KRB_CMP_E(key1B, key2B)
+# define KRB_R_IS_IDENTICAL(key1B, key2B, key1E, key2E) KRB_CMP_E(key1B, key2B)
+#endif
+
+
+/** Is the node red or black?
+ * @returns true / false
+ * @param pNode Pointer to the node in question.
+ * @remarks All NULL pointers are considered black leaf nodes.
+ */
+#define KRB_IS_RED(pNode) ( (pNode) != NULL && (pNode)->mfIsRed )
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * Stack used to avoid recursive calls during insert and removal.
+ */
+typedef struct
+{
+ unsigned cEntries;
+ KRBTREEPTR *aEntries[KRB_MAX_STACK];
+} KRB_INT(STACK);
+
+/**
+ * The callback used by the Destroy and DoWithAll functions.
+ */
+typedef int (* KRB_TYPE(PFN,CALLBACK))(KRBNODE *, void *);
+
+#ifdef KRB_NEED_KRBROOT
+/**
+ * The Red-Black tree root structure.
+ */
+typedef struct
+{
+ KRBTREEPTR mpRoot;
+# ifdef KRB_CACHE_SIZE
+ KRBTREEPTR maLookthru[KRB_CACHE_SIZE];
+# endif
+} KRBROOT;
+#endif
+
+
+
+/**
+ * Initializes the root of the Red-Black tree.
+ *
+ * @param pTree Pointer to the root structure.
+ */
+KRB_DECL(void) KRB_FN(Init)(KRBROOT *pRoot)
+{
+#ifdef KRB_CACHE_SIZE
+ unsigned i;
+#endif
+
+ pRoot->mpRoot = KRB_NULL;
+#ifdef KRB_CACHE_SIZE
+ for (i = 0; i < (KRB_CACHE_SIZE); i++)
+ pRoot->maLookthru[i] = KRB_NULL;
+#endif
+}
+
+
+/**
+ * Rotates the tree to the left (shift direction) and recolors the nodes.
+ *
+ * @pre
+ *
+ * 2 4
+ * / \ / \
+ * 1 4 ==> 2 5
+ * / \ / \
+ * 3 5 1 3
+ *
+ * @endpre
+ *
+ * @returns The new root node.
+ * @param pRoot The root node.
+ *
+ * @remarks This will not update any pointer <tt>to</tt> the root node!
+ */
+K_DECL_INLINE(KRBNODE *) KAVL_FN(RotateLeft)(KRBNODE *pRoot)
+{
+ KRBNODE *pNewRoot = pRoot->mRight;
+ pRoot->mRight = pNewRoot->mLeft;
+ pNewRoot->mLeft = pRoot;
+
+ pRoot->mfIsRed = 1;
+ pNewRoot->mfIsRed = 0;
+ return pNewRoot;
+}
+
+
+/**
+ * Rotates the tree to the right (shift direction) and recolors the nodes.
+ *
+ * @pre
+ *
+ * 4 2
+ * / \ / \
+ * 2 5 ==> 1 4
+ * / \ / \
+ * 1 3 3 5
+ *
+ * @endpre
+ *
+ * @returns The new root node.
+ * @param pRoot The root node.
+ *
+ * @remarks This will not update any pointer <tt>to</tt> the root node!
+ */
+K_DECL_INLINE(KRBNODE *) KAVL_FN(RotateRight)(KRBNODE *pRoot)
+{
+ KRBNODE *pNewRoot = pRoot->mLeft;
+ pRoot->mLeft = pNewRoot->mRight;
+ pNewRoot->mRight = pRoot;
+
+ pRoot->mfIsRed = 1;
+ pNewRoot->mfIsRed = 0;
+ return pNewRoot;
+}
+
+
+/**
+ * Performs a double left rotation with recoloring.
+ *
+ * @pre
+ *
+ * 2 2 4
+ * / \ / \ / \
+ * 1 6 ==> 1 4 ==> 2 6
+ * / \ / \ / \ / \
+ * 4 7 3 6 1 3 5 7
+ * / \ / \
+ * 3 5 5 7
+ * @endpre
+ *
+ * @returns The new root node.
+ * @param pRoot The root node.
+ *
+ * @remarks This will not update any pointer <tt>to</tt> the root node!
+ */
+K_DECL_INLINE(KRBNODE *) KAVL_FN(DoubleRotateLeft)(KRBNODE *pRoot)
+{
+ pRoot->mRight = KAVL_FN(RotateRight)(pRoot->mRight);
+ return KAVL_FN(RotateLeft)(pRoot);
+}
+
+
+/**
+ * Performs a double right rotation with recoloring.
+ *
+ * @pre
+ * 6 6 4
+ * / \ / \ / \
+ * 2 7 4 7 2 6
+ * / \ ==> / \ ==> / \ / \
+ * 1 4 2 5 1 3 5 7
+ * / \ / \
+ * 3 5 1 3
+ *
+ * @endpre
+ *
+ * @returns The new root node.
+ * @param pRoot The root node.
+ *
+ * @remarks This will not update any pointer <tt>to</tt> the root node!
+ */
+K_DECL_INLINE(KRBNODE *) KAVL_FN(DoubleRotateRight)(KRBNODE *pRoot)
+{
+ pRoot->mLeft = KAVL_FN(RotateLeft)(pRoot->mLeft);
+ return KAVL_FN(RotateRight)(pRoot);
+}
+
+
+/**
+ * Inserts a node into the Red-Black tree.
+ * @returns K_TRUE if inserted.
+ * K_FALSE if node exists in tree.
+ * @param pRoot Pointer to the Red-Back tree's root structure.
+ * @param pNode Pointer to the node which is to be added.
+ */
+KRB_DECL(KBOOL) KRB_FN(Insert)(KRBROOT *pRoot, KRBNODE *pNode)
+{
+ KRBTREEPTR *ppCurNode = &pRoot->mpRoot;
+ register KRBKEY Key = pNode->mKey;
+#ifdef KRB_RANGE
+ register KRBKEY KeyLast = pNode->mKeyLast;
+#endif
+
+#ifdef KRB_RANGE
+ if (Key > KeyLast)
+ return K_FALSE;
+#endif
+
+ KRB_WRITE_LOCK(pRoot);
+
+ Stack.cEntries = 0;
+ while (*ppCurNode != KRB_NULL)
+ {
+ register KRBNODE *pCurNode = KRB_GET_POINTER(ppCurNode);
+
+ kHlpAssert(Stack.cEntries < KRB_MAX_STACK);
+ Stack.aEntries[Stack.cEntries++] = ppCurNode;
+#ifdef KRB_EQUAL_ALLOWED
+ if (KRB_R_IS_IDENTICAL(pCurNode->mKey, Key, pCurNode->mKeyLast, KeyLast))
+ {
+ /*
+ * If equal then we'll use a list of equal nodes.
+ */
+ pNode->mpLeft = pNode->mpRight = KRB_NULL;
+ pNode->mHeight = 0;
+ KRB_SET_POINTER_NULL(&pNode->mpList, &pCurNode->mpList);
+ KRB_SET_POINTER(&pCurNode->mpList, pNode);
+ KRB_WRITE_UNLOCK(pRoot);
+ return K_TRUE;
+ }
+#endif
+#ifdef KRB_CHECK_FOR_EQUAL_INSERT
+ if (KRB_R_IS_INTERSECTING(pCurNode->mKey, Key, pCurNode->mKeyLast, KeyLast))
+ {
+ KRB_WRITE_UNLOCK(pRoot);
+ return K_FALSE;
+ }
+#endif
+ if (KRB_CMP_G(pCurNode->mKey, Key))
+ ppCurNode = &pCurNode->mpLeft;
+ else
+ ppCurNode = &pCurNode->mpRight;
+ }
+
+ pNode->mpLeft = pNode->mpRight = KRB_NULL;
+#ifdef KRB_EQUAL_ALLOWED
+ pNode->mpList = KRB_NULL;
+#endif
+ pNode->mHeight = 1;
+ KRB_SET_POINTER(ppCurNode, pNode);
+
+ KRB_FN(Rebalance)(&Stack);
+
+ KRB_WRITE_UNLOCK(pRoot);
+ return K_TRUE;
+}
+
+
+/**
+ * Removes a node from the Red-Black tree.
+ * @returns Pointer to the node.
+ * @param pRoot Pointer to the Red-Back tree's root structure.
+ * @param Key Key value of the node which is to be removed.
+ * @sketch Find the node which is to be removed:
+ * LOOP until not found
+ * BEGIN
+ * Add node pointer pointer to the AVL-stack.
+ * IF the keys matches THEN break!
+ * IF remove key < node key THEN
+ * left
+ * ELSE
+ * right
+ * END
+ * IF found THEN
+ * BEGIN
+ * IF left node not empty THEN
+ * BEGIN
+ * Find the right most node in the left tree while adding the pointer to the pointer to it's parent to the stack:
+ * Start at left node.
+ * LOOP until right node is empty
+ * BEGIN
+ * Add to stack.
+ * go right.
+ * END
+ * Link out the found node.
+ * Replace the node which is to be removed with the found node.
+ * Correct the stack entry for the pointer to the left tree.
+ * END
+ * ELSE
+ * BEGIN
+ * Move up right node.
+ * Remove last stack entry.
+ * END
+ * Balance tree using stack.
+ * END
+ * return pointer to the removed node (if found).
+ */
+KRB_DECL(KRBNODE *) KRB_FN(Remove)(KRBROOT *pRoot, KRBKEY Key)
+{
+ KRB_INT(STACK) Stack;
+ KRBTREEPTR *ppDeleteNode = &pRoot->mpRoot;
+ register KRBNODE *pDeleteNode;
+
+ KRB_WRITE_LOCK(pRoot);
+
+ Stack.cEntries = 0;
+ for (;;)
+ {
+ if (*ppDeleteNode == KRB_NULL)
+ {
+ KRB_WRITE_UNLOCK(pRoot);
+ return NULL;
+ }
+ pDeleteNode = KRB_GET_POINTER(ppDeleteNode);
+
+ kHlpAssert(Stack.cEntries < KRB_MAX_STACK);
+ Stack.aEntries[Stack.cEntries++] = ppDeleteNode;
+ if (KRB_CMP_E(pDeleteNode->mKey, Key))
+ break;
+
+ if (KRB_CMP_G(pDeleteNode->mKey, Key))
+ ppDeleteNode = &pDeleteNode->mpLeft;
+ else
+ ppDeleteNode = &pDeleteNode->mpRight;
+ }
+
+ if (pDeleteNode->mpLeft != KRB_NULL)
+ {
+ /* find the rightmost node in the left tree. */
+ const unsigned iStackEntry = Stack.cEntries;
+ KRBTREEPTR *ppLeftLeast = &pDeleteNode->mpLeft;
+ register KRBNODE *pLeftLeast = KRB_GET_POINTER(ppLeftLeast);
+
+ while (pLeftLeast->mpRight != KRB_NULL)
+ {
+ kHlpAssert(Stack.cEntries < KRB_MAX_STACK);
+ Stack.aEntries[Stack.cEntries++] = ppLeftLeast;
+ ppLeftLeast = &pLeftLeast->mpRight;
+ pLeftLeast = KRB_GET_POINTER(ppLeftLeast);
+ }
+
+ /* link out pLeftLeast */
+ KRB_SET_POINTER_NULL(ppLeftLeast, &pLeftLeast->mpLeft);
+
+ /* link it in place of the delete node. */
+ KRB_SET_POINTER_NULL(&pLeftLeast->mpLeft, &pDeleteNode->mpLeft);
+ KRB_SET_POINTER_NULL(&pLeftLeast->mpRight, &pDeleteNode->mpRight);
+ pLeftLeast->mHeight = pDeleteNode->mHeight;
+ KRB_SET_POINTER(ppDeleteNode, pLeftLeast);
+ Stack.aEntries[iStackEntry] = &pLeftLeast->mpLeft;
+ }
+ else
+ {
+ KRB_SET_POINTER_NULL(ppDeleteNode, &pDeleteNode->mpRight);
+ Stack.cEntries--;
+ }
+
+ KRB_FN(Rebalance)(&Stack);
+
+ KRB_CACHE_INVALIDATE_NODE(pRoot, pDeleteNode, Key);
+
+ KRB_WRITE_UNLOCK(pRoot);
+ return pDeleteNode;
+}
+
diff --git a/src/lib/kStuff/include/k/kRbTmpl/kRbDestroy.h b/src/lib/kStuff/include/k/kRbTmpl/kRbDestroy.h
new file mode 100644
index 0000000..0300a9a
--- /dev/null
+++ b/src/lib/kStuff/include/k/kRbTmpl/kRbDestroy.h
@@ -0,0 +1,129 @@
+/* $Id: kRbDestroy.h 35 2009-11-08 19:39:03Z bird $ */
+/** @file
+ * kRbTmpl - Templated Red-Black Trees, Destroy the tree.
+ */
+
+/*
+ * Copyright (c) 1999-2009 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.
+ */
+
+/**
+ * Destroys the specified tree, starting with the root node and working our way down.
+ *
+ * @returns 0 on success.
+ * @returns Return value from callback on failure. On failure, the tree will be in
+ * an unbalanced condition and only further calls to the Destroy should be
+ * made on it. Note that the node we fail on will be considered dead and
+ * no action is taken to link it back into the tree.
+ * @param pRoot Pointer to the Red-Back tree's root structure.
+ * @param pfnCallBack Pointer to callback function.
+ * @param pvUser User parameter passed on to the callback function.
+ */
+KRB_DECL(int) KRB_FN(Destroy)(KRBROOT *pRoot, KRB_TYPE(PFN,CALLBACK) pfnCallBack, void *pvUser)
+{
+#ifdef KRB_CACHE_SIZE
+ unsigned i;
+#endif
+ unsigned cEntries;
+ KRBNODE *apEntries[KRB_MAX_STACK];
+ int rc;
+
+ KRB_WRITE_LOCK(pRoot);
+ if (pRoot->mpRoot == KRB_NULL)
+ {
+ KRB_WRITE_UNLOCK(pRoot);
+ return 0;
+ }
+
+#ifdef KRB_CACHE_SIZE
+ /*
+ * Kill the lookthru cache.
+ */
+ for (i = 0; i < (KRB_CACHE_SIZE); i++)
+ pRoot->maLookthru[i] = KRB_NULL;
+#endif
+
+ cEntries = 1;
+ apEntries[0] = KRB_GET_POINTER(&pRoot->mpRoot);
+ while (cEntries > 0)
+ {
+ /*
+ * Process the subtrees first.
+ */
+ KRBNODE *pNode = apEntries[cEntries - 1];
+ if (pNode->mpLeft != KRB_NULL)
+ apEntries[cEntries++] = KRB_GET_POINTER(&pNode->mpLeft);
+ else if (pNode->mpRight != KRB_NULL)
+ apEntries[cEntries++] = KRB_GET_POINTER(&pNode->mpRight);
+ else
+ {
+#ifdef KRB_EQUAL_ALLOWED
+ /*
+ * Process nodes with the same key.
+ */
+ while (pNode->pList != KRB_NULL)
+ {
+ KRBNODE *pEqual = KRB_GET_POINTER(&pNode->pList);
+ KRB_SET_POINTER(&pNode->pList, KRB_GET_POINTER_NULL(&pEqual->pList));
+ pEqual->pList = KRB_NULL;
+
+ rc = pfnCallBack(pEqual, pvUser);
+ if (rc)
+ {
+ KRB_WRITE_UNLOCK(pRoot);
+ return rc;
+ }
+ }
+#endif
+
+ /*
+ * Unlink the node.
+ */
+ if (--cEntries > 0)
+ {
+ KRBNODE *pParent = apEntries[cEntries - 1];
+ if (KRB_GET_POINTER(&pParent->mpLeft) == pNode)
+ pParent->mpLeft = KRB_NULL;
+ else
+ pParent->mpRight = KRB_NULL;
+ }
+ else
+ pRoot->mpRoot = KRB_NULL;
+
+ kHlpAssert(pNode->mpLeft == KRB_NULL);
+ kHlpAssert(pNode->mpRight == KRB_NULL);
+ rc = pfnCallBack(pNode, pvUser);
+ if (rc)
+ {
+ KRB_WRITE_UNLOCK(pRoot);
+ return rc;
+ }
+ }
+ } /* while */
+ kHlpAssert(pRoot->mpRoot == KRB_NULL);
+
+ KRB_WRITE_UNLOCK(pRoot);
+ return 0;
+}
+
diff --git a/src/lib/kStuff/include/k/kRbTmpl/kRbDoWithAll.h b/src/lib/kStuff/include/k/kRbTmpl/kRbDoWithAll.h
new file mode 100644
index 0000000..a9de71c
--- /dev/null
+++ b/src/lib/kStuff/include/k/kRbTmpl/kRbDoWithAll.h
@@ -0,0 +1,166 @@
+/* $Id: kRbDoWithAll.h 35 2009-11-08 19:39:03Z bird $ */
+/** @file
+ * kRbTmpl - Templated Red-Black Trees, The Callback Iterator.
+ */
+
+/*
+ * Copyright (c) 1999-2009 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.
+ */
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * Stack used by DoWithAll to avoid recusive function calls.
+ */
+typedef struct
+{
+ unsigned cEntries;
+ KRBNODE *aEntries[KRB_MAX_STACK];
+ char achFlags[KRB_MAX_STACK];
+ KRBROOT pRoot;
+} KRB_INT(STACK2);
+
+
+/**
+ * Iterates thru all nodes in the given tree.
+ *
+ * @returns 0 on success. Return from callback on failure.
+ * @param pRoot Pointer to the Red-Back tree's root structure.
+ * @param fFromLeft K_TRUE: Left to right.
+ * K_FALSE: Right to left.
+ * @param pfnCallBack Pointer to callback function.
+ * @param pvUser User parameter passed on to the callback function.
+ */
+KRB_DECL(int) KRB_FN(DoWithAll)(KRBROOT *pRoot, KBOOL fFromLeft, KRB_TYPE(PFN,CALLBACK) pfnCallBack, void *pvUser)
+{
+ KRB_INT(STACK2) Stack;
+ KRBNODE *pNode;
+#ifdef KRB_EQUAL_ALLOWED
+ KRBNODE *pEqual;
+#endif
+ int rc;
+
+ KRB_READ_LOCK(pRoot);
+ if (pRoot->mpRoot == KRB_NULL)
+ {
+ KRB_READ_UNLOCK(pRoot);
+ return 0;
+ }
+
+ Stack.cEntries = 1;
+ Stack.achFlags[0] = 0;
+ Stack.aEntries[0] = KRB_GET_POINTER(&pRoot->mpRoot);
+
+ if (fFromLeft)
+ { /* from left */
+ while (Stack.cEntries > 0)
+ {
+ pNode = Stack.aEntries[Stack.cEntries - 1];
+
+ /* left */
+ if (!Stack.achFlags[Stack.cEntries - 1]++)
+ {
+ if (pNode->mpLeft != KRB_NULL)
+ {
+ Stack.achFlags[Stack.cEntries] = 0; /* 0 first, 1 last */
+ Stack.aEntries[Stack.cEntries++] = KRB_GET_POINTER(&pNode->mpLeft);
+ continue;
+ }
+ }
+
+ /* center */
+ rc = pfnCallBack(pNode, pvUser);
+ if (rc)
+ return rc;
+#ifdef KRB_EQUAL_ALLOWED
+ if (pNode->mpList != KRB_NULL)
+ for (pEqual = KRB_GET_POINTER(&pNode->mpList); pEqual; pEqual = KRB_GET_POINTER_NULL(&pEqual->mpList))
+ {
+ rc = pfnCallBack(pEqual, pvUser);
+ if (rc)
+ {
+ KRB_READ_UNLOCK(pRoot);
+ return rc;
+ }
+ }
+#endif
+
+ /* right */
+ Stack.cEntries--;
+ if (pNode->mpRight != KRB_NULL)
+ {
+ Stack.achFlags[Stack.cEntries] = 0;
+ Stack.aEntries[Stack.cEntries++] = KRB_GET_POINTER(&pNode->mpRight);
+ }
+ } /* while */
+ }
+ else
+ { /* from right */
+ while (Stack.cEntries > 0)
+ {
+ pNode = Stack.aEntries[Stack.cEntries - 1];
+
+ /* right */
+ if (!Stack.achFlags[Stack.cEntries - 1]++)
+ {
+ if (pNode->mpRight != KRB_NULL)
+ {
+ Stack.achFlags[Stack.cEntries] = 0; /* 0 first, 1 last */
+ Stack.aEntries[Stack.cEntries++] = KRB_GET_POINTER(&pNode->mpRight);
+ continue;
+ }
+ }
+
+ /* center */
+ rc = pfnCallBack(pNode, pvUser);
+ if (rc)
+ return rc;
+#ifdef KRB_EQUAL_ALLOWED
+ if (pNode->mpList != KRB_NULL)
+ for (pEqual = KRB_GET_POINTER(&pNode->mpList); pEqual; pEqual = KRB_GET_POINTER_NULL(&pEqual->pList))
+ {
+ rc = pfnCallBack(pEqual, pvUser);
+ if (rc)
+ {
+ KRB_READ_UNLOCK(pRoot);
+ return rc;
+ }
+ }
+#endif
+
+ /* left */
+ Stack.cEntries--;
+ if (pNode->mpLeft != KRB_NULL)
+ {
+ Stack.achFlags[Stack.cEntries] = 0;
+ Stack.aEntries[Stack.cEntries++] = KRB_GET_POINTER(&pNode->mpLeft);
+ }
+ } /* while */
+ }
+
+ KRB_READ_UNLOCK(pRoot);
+ return 0;
+}
+
diff --git a/src/lib/kStuff/include/k/kRbTmpl/kRbEnum.h b/src/lib/kStuff/include/k/kRbTmpl/kRbEnum.h
new file mode 100644
index 0000000..d022410
--- /dev/null
+++ b/src/lib/kStuff/include/k/kRbTmpl/kRbEnum.h
@@ -0,0 +1,187 @@
+/* $Id: kRbEnum.h 35 2009-11-08 19:39:03Z bird $ */
+/** @file
+ * kRbTmpl - Templated Red-Black Trees, Node Enumeration.
+ */
+
+/*
+ * Copyright (c) 1999-2009 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.
+ */
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * Enumeration control data.
+ *
+ * This is initialized by BeginEnum and used by GetNext to figure out what
+ * to do next.
+ */
+typedef struct KRB_TYPE(,ENUMDATA)
+{
+ KBOOL fFromLeft;
+ KI8 cEntries;
+ KU8 achFlags[KRB_MAX_STACK];
+ KRBNODE * aEntries[KRB_MAX_STACK];
+} KRB_TYPE(,ENUMDATA), *KRB_TYPE(P,ENUMDATA);
+
+
+/**
+ * Ends an enumeration.
+ *
+ * The purpose of this function is to unlock the tree should the Red-Black tree
+ * implementation include locking. It's good practice to call it anyway even if
+ * the tree doesn't do any locking.
+ *
+ * @param pEnumData Pointer to enumeration control data.
+ */
+KRB_DECL(void) KRB_FN(EndEnum)(KRB_TYPE(,ENUMDATA) *pEnumData)
+{
+ KRBROOT pRoot = pEnumData->pRoot;
+ pEnumData->pRoot = NULL;
+ if (pRoot)
+ KRB_READ_UNLOCK(pEnumData->pRoot);
+}
+
+
+/**
+ * Get the next node in the tree enumeration.
+ *
+ * The current implementation of this function willl not walk the mpList
+ * chain like the DoWithAll function does. This may be changed later.
+ *
+ * @returns Pointer to the next node in the tree.
+ * NULL is returned when the end of the tree has been reached,
+ * it is not necessary to call EndEnum in this case.
+ * @param pEnumData Pointer to enumeration control data.
+ */
+KRB_DECL(KRBNODE *) KRB_FN(GetNext)(KRB_TYPE(,ENUMDATA) *pEnumData)
+{
+ if (pEnumData->fFromLeft)
+ { /* from left */
+ while (pEnumData->cEntries > 0)
+ {
+ KRBNODE *pNode = pEnumData->aEntries[pEnumData->cEntries - 1];
+
+ /* left */
+ if (pEnumData->achFlags[pEnumData->cEntries - 1] == 0)
+ {
+ pEnumData->achFlags[pEnumData->cEntries - 1]++;
+ if (pNode->mpLeft != KRB_NULL)
+ {
+ pEnumData->achFlags[pEnumData->cEntries] = 0; /* 0 left, 1 center, 2 right */
+ pEnumData->aEntries[pEnumData->cEntries++] = KRB_GET_POINTER(&pNode->mpLeft);
+ continue;
+ }
+ }
+
+ /* center */
+ if (pEnumData->achFlags[pEnumData->cEntries - 1] == 1)
+ {
+ pEnumData->achFlags[pEnumData->cEntries - 1]++;
+ return pNode;
+ }
+
+ /* right */
+ pEnumData->cEntries--;
+ if (pNode->mpRight != KRB_NULL)
+ {
+ pEnumData->achFlags[pEnumData->cEntries] = 0;
+ pEnumData->aEntries[pEnumData->cEntries++] = KRB_GET_POINTER(&pNode->mpRight);
+ }
+ } /* while */
+ }
+ else
+ { /* from right */
+ while (pEnumData->cEntries > 0)
+ {
+ KRBNODE *pNode = pEnumData->aEntries[pEnumData->cEntries - 1];
+
+ /* right */
+ if (pEnumData->achFlags[pEnumData->cEntries - 1] == 0)
+ {
+ pEnumData->achFlags[pEnumData->cEntries - 1]++;
+ if (pNode->mpRight != KRB_NULL)
+ {
+ pEnumData->achFlags[pEnumData->cEntries] = 0; /* 0 right, 1 center, 2 left */
+ pEnumData->aEntries[pEnumData->cEntries++] = KRB_GET_POINTER(&pNode->mpRight);
+ continue;
+ }
+ }
+
+ /* center */
+ if (pEnumData->achFlags[pEnumData->cEntries - 1] == 1)
+ {
+ pEnumData->achFlags[pEnumData->cEntries - 1]++;
+ return pNode;
+ }
+
+ /* left */
+ pEnumData->cEntries--;
+ if (pNode->mpLeft != KRB_NULL)
+ {
+ pEnumData->achFlags[pEnumData->cEntries] = 0;
+ pEnumData->aEntries[pEnumData->cEntries++] = KRB_GET_POINTER(&pNode->mpLeft);
+ }
+ } /* while */
+ }
+
+ /*
+ * Call EndEnum.
+ */
+ KRB_FN(EndEnum)(pEnumData);
+ return NULL;
+}
+
+
+/**
+ * Starts an enumeration of all nodes in the given tree.
+ *
+ * The current implementation of this function will not walk the mpList
+ * chain like the DoWithAll function does. This may be changed later.
+ *
+ * @returns Pointer to the first node in the enumeration.
+ * If NULL is returned the tree is empty calling EndEnum isn't
+ * strictly necessary (although it will do no harm).
+ * @param pRoot Pointer to the Red-Back tree's root structure.
+ * @param pEnumData Pointer to enumeration control data.
+ * @param fFromLeft K_TRUE: Left to right.
+ * K_FALSE: Right to left.
+ */
+KRB_DECL(KRBNODE *) KRB_FN(BeginEnum)(KRBROOT *pRoot, KRB_TYPE(,ENUMDATA) *pEnumData, KBOOL fFromLeft)
+{
+ KRB_READ_LOCK(pRoot);
+ pEnumData->pRoot = pRoot;
+ if (pRoot->mpRoot != KRB_NULL)
+ {
+ pEnumData->fFromLeft = fFromLeft;
+ pEnumData->cEntries = 1;
+ pEnumData->aEntries[0] = KRB_GET_POINTER(pRoot->mpRoot);
+ pEnumData->achFlags[0] = 0;
+ }
+ else
+ pEnumData->cEntries = 0;
+
+ return KRB_FN(GetNext)(pEnumData);
+}
+
diff --git a/src/lib/kStuff/include/k/kRbTmpl/kRbGet.h b/src/lib/kStuff/include/k/kRbTmpl/kRbGet.h
new file mode 100644
index 0000000..b03d4e1
--- /dev/null
+++ b/src/lib/kStuff/include/k/kRbTmpl/kRbGet.h
@@ -0,0 +1,89 @@
+/* $Id: kRbGet.h 35 2009-11-08 19:39:03Z bird $ */
+/** @file
+ * kRbTmpl - Templated Red-Black Trees, Get a Node.
+ */
+
+/*
+ * Copyright (c) 1999-2009 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.
+ */
+
+/**
+ * Gets a node from the tree (does not remove it!)
+ *
+ * @returns Pointer to the node holding the given key.
+ * @param pRoot Pointer to the Red-Back tree's root structure.
+ * @param Key Key value of the node which is to be found.
+ */
+KRB_DECL(KRBNODE *) KRB_FN(Get)(KRBROOT *pRoot, KRBKEY Key)
+{
+ KRBNODE *pNode;
+#ifdef KRB_CACHE_SIZE
+ KRBTREEPTR *ppEntry;
+#endif
+
+ KRB_READ_LOCK(pRoot);
+ if (pRoot->mpRoot == KRB_NULL)
+ {
+ KRB_READ_UNLOCK(pRoot);
+ return NULL;
+ }
+
+#ifdef KRB_CACHE_SIZE
+ ppEntry = &pRoot->maLookthru[KRB_CACHE_HASH(Key)];
+ pNode = KRB_GET_POINTER_NULL(ppEntry);
+ if (!pNode || KRB_CMP_NE(pNode->mKey, Key))
+#endif
+ {
+ pNode = KRB_GET_POINTER(&pRoot->mpRoot);
+ while (KRB_CMP_NE(pNode->mKey, Key))
+ {
+ if (KRB_CMP_G(pNode->mKey, Key))
+ {
+ if (pNode->mpLeft == KRB_NULL)
+ {
+ KRB_READ_UNLOCK(pRoot);
+ return NULL;
+ }
+ pNode = KRB_GET_POINTER(&pNode->mpLeft);
+ }
+ else
+ {
+ if (pNode->mpRight == KRB_NULL)
+ {
+ KRB_READ_UNLOCK(pRoot);
+ return NULL;
+ }
+ pNode = KRB_GET_POINTER(&pNode->mpRight);
+ }
+ }
+
+#ifdef KRB_CACHE_SIZE
+ KRB_SET_POINTER(ppEntry, pNode);
+#endif
+ }
+
+ KRB_READ_UNLOCK(pRoot);
+ return pNode;
+}
+
diff --git a/src/lib/kStuff/include/k/kRbTmpl/kRbGetBestFit.h b/src/lib/kStuff/include/k/kRbTmpl/kRbGetBestFit.h
new file mode 100644
index 0000000..bfda27a
--- /dev/null
+++ b/src/lib/kStuff/include/k/kRbTmpl/kRbGetBestFit.h
@@ -0,0 +1,112 @@
+/* $Id: kRbGetBestFit.h 35 2009-11-08 19:39:03Z bird $ */
+/** @file
+ * kRbTmpl - Templated Red-Black Trees, Get Best Fitting Node.
+ */
+
+/*
+ * Copyright (c) 1999-2009 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.
+ */
+
+/**
+ * Finds the best fitting node in the tree for the given Key value.
+ *
+ * @returns Pointer to the best fitting node found.
+ * @param pRoot Pointer to the Red-Back tree's root structure.
+ * @param Key The Key of which is to be found a best fitting match for..
+ * @param fAbove K_TRUE: Returned node is have the closest key to Key from above.
+ * K_FALSE: Returned node is have the closest key to Key from below.
+ * @sketch The best fitting node is always located in the searchpath above you.
+ * >= (above): The node where you last turned left.
+ * <= (below): the node where you last turned right.
+ */
+KRB_DECL(KRBNODE *) KRB_FN(GetBestFit)(KRBROOT *pRoot, KRBKEY Key, KBOOL fAbove)
+{
+ register KRBNODE *pNode;
+ KRBNODE *pNodeLast;
+
+ KRB_READ_LOCK(pLook);
+ if (pRoot->mpRoot == KRB_NULL)
+ {
+ KRB_READ_UNLOCK(pLook);
+ return NULL;
+ }
+
+ pNode = KRB_GET_POINTER(&pRoot->mpRoot);
+ pNodeLast = NULL;
+ if (fAbove)
+ { /* pNode->mKey >= Key */
+ while (KRB_CMP_NE(pNode->mKey, Key))
+ {
+ if (KRB_CMP_G(pNode->mKey, Key))
+ {
+ if (pNode->mpLeft == KRB_NULL)
+ {
+ KRB_READ_UNLOCK(pLook);
+ return pNode;
+ }
+ pNodeLast = pNode;
+ pNode = KRB_GET_POINTER(&pNode->mpLeft);
+ }
+ else
+ {
+ if (pNode->mpRight == KRB_NULL)
+ {
+ KRB_READ_UNLOCK(pLook);
+ return pNodeLast;
+ }
+ pNode = KRB_GET_POINTER(&pNode->mpRight);
+ }
+ }
+ }
+ else
+ { /* pNode->mKey <= Key */
+ while (KRB_CMP_NE(pNode->mKey, Key))
+ {
+ if (KRB_CMP_G(pNode->mKey, Key))
+ {
+ if (pNode->mpLeft == KRB_NULL)
+ {
+ KRB_READ_UNLOCK(pLook);
+ return pNodeLast;
+ }
+ pNode = KRB_GET_POINTER(&pNode->mpLeft);
+ }
+ else
+ {
+ if (pNode->mpRight == KRB_NULL)
+ {
+ KRB_READ_UNLOCK(pLook);
+ return pNode;
+ }
+ pNodeLast = pNode;
+ pNode = KRB_GET_POINTER(&pNode->mpRight);
+ }
+ }
+ }
+
+ /* perfect match or nothing. */
+ KRB_READ_UNLOCK(pLook);
+ return pNode;
+}
+
diff --git a/src/lib/kStuff/include/k/kRbTmpl/kRbGetWithParent.h b/src/lib/kStuff/include/k/kRbTmpl/kRbGetWithParent.h
new file mode 100644
index 0000000..05a7d8c
--- /dev/null
+++ b/src/lib/kStuff/include/k/kRbTmpl/kRbGetWithParent.h
@@ -0,0 +1,65 @@
+/* $Id: kRbGetWithParent.h 35 2009-11-08 19:39:03Z bird $ */
+/** @file
+ * kRbTmpl - Templated Red-Black Trees, Get Node With Parent.
+ */
+
+/*
+ * Copyright (c) 1999-2009 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.
+ */
+
+/**
+ * Gets a node from the tree and its parent node (if any).
+ * The tree remains unchanged.
+ *
+ * @returns Pointer to the node holding the given key.
+ * @param pRoot Pointer to the Red-Back tree's root structure.
+ * @param ppParent Pointer to a variable which will hold the pointer to the partent node on
+ * return. When no node is found, this will hold the last searched node.
+ * @param Key Key value of the node which is to be found.
+ */
+KRB_DECL(KRBNODE *) KRB_FN(GetWithParent)(KRBROOT *pRoot, KRBNODE **ppParent, KRBKEY Key)
+{
+ register KRBNODE *pNode;
+ register KRBNODE *pParent;
+
+ KRB_READ_LOCK(pRoot);
+
+ pParent = NULL;
+ pNode = KRB_GET_POINTER_NULL(&pRoot->mpRoot);
+ while ( pNode != NULL
+ && KRB_CMP_NE(pNode->mKey, Key))
+ {
+ pParent = pNode;
+ if (KRB_CMP_G(pNode->mKey, Key))
+ pNode = KRB_GET_POINTER_NULL(&pNode->mpLeft);
+ else
+ pNode = KRB_GET_POINTER_NULL(&pNode->mpRight);
+ }
+
+ KRB_READ_UNLOCK(pRoot);
+
+ *ppParent = pParent;
+ return pNode;
+}
+
diff --git a/src/lib/kStuff/include/k/kRbTmpl/kRbRemove2.h b/src/lib/kStuff/include/k/kRbTmpl/kRbRemove2.h
new file mode 100644
index 0000000..deed81d
--- /dev/null
+++ b/src/lib/kStuff/include/k/kRbTmpl/kRbRemove2.h
@@ -0,0 +1,133 @@
+/* $Id: kRbRemove2.h 35 2009-11-08 19:39:03Z bird $ */
+/** @file
+ * kRbTmpl - Templated Red-Black Trees, Remove A Specific Node.
+ */
+
+/*
+ * Copyright (c) 1999-2009 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.
+ */
+
+/**
+ * Removes the specified node from the tree.
+ *
+ * @returns Pointer to the removed node (NULL if not in the tree)
+ * @param pRoot Pointer to the Red-Back tree's root structure.
+ * @param Key The Key of which is to be found a best fitting match for..
+ *
+ * @remark This implementation isn't the most efficient, but this short and
+ * easier to manage.
+ */
+KRB_DECL(KRBNODE *) KRB_FN(Remove2)(KRBROOT *pRoot, KRBNODE *pNode)
+{
+#ifdef KRB_EQUAL_ALLOWED
+ /*
+ * Find the right node by key and see if it's what we want.
+ */
+ KRBNODE *pParent;
+ KRBNODE *pCurNode = KRB_FN(GetWithParent)(pRoot, pNode->mKey, &pParent);
+ if (!pCurNode)
+ return NULL;
+ KRB_WRITE_LOCK(pRoot); /** @todo the locking here isn't 100% sane. The only way to archive that is by no calling worker functions. */
+ if (pCurNode != pNode)
+ {
+ /*
+ * It's not the one we want, but it could be in the duplicate list.
+ */
+ while (pCurNode->mpList != KRB_NULL)
+ {
+ KRBNODE *pNext = KRB_GET_POINTER(&pCurNode->mpList);
+ if (pNext == pNode)
+ {
+ KRB_SET_POINTER_NULL(&pCurNode->mpList, KRB_GET_POINTER_NULL(&pNode->mpList));
+ pNode->mpList = KRB_NULL;
+ KRB_CACHE_INVALIDATE_NODE(pRoot, pNode, pNode->mKey);
+ KRB_WRITE_UNLOCK(pRoot);
+ return pNode;
+ }
+ pCurNode = pNext;
+ }
+ KRB_WRITE_UNLOCK(pRoot);
+ return NULL;
+ }
+
+ /*
+ * Ok, it's the one we want alright.
+ *
+ * Simply remove it if it's the only one with they Key,
+ * if there are duplicates we'll have to unlink it and
+ * insert the first duplicate in our place.
+ */
+ if (pNode->mpList == KRB_NULL)
+ {
+ KRB_WRITE_UNLOCK(pRoot);
+ KRB_FN(Remove)(pRoot, pNode->mKey);
+ }
+ else
+ {
+ KRBNODE *pNewUs = KRB_GET_POINTER(&pNode->mpList);
+
+ pNewUs->mHeight = pNode->mHeight;
+
+ if (pNode->mpLeft != KRB_NULL)
+ KRB_SET_POINTER(&pNewUs->mpLeft, KRB_GET_POINTER(&pNode->mpLeft))
+ else
+ pNewUs->mpLeft = KRB_NULL;
+
+ if (pNode->mpRight != KRB_NULL)
+ KRB_SET_POINTER(&pNewUs->mpRight, KRB_GET_POINTER(&pNode->mpRight))
+ else
+ pNewUs->mpRight = KRB_NULL;
+
+ if (pParent)
+ {
+ if (KRB_GET_POINTER_NULL(&pParent->mpLeft) == pNode)
+ KRB_SET_POINTER(&pParent->mpLeft, pNewUs);
+ else
+ KRB_SET_POINTER(&pParent->mpRight, pNewUs);
+ }
+ else
+ KRB_SET_POINTER(&pRoot->mpRoot, pNewUs);
+
+ KRB_CACHE_INVALIDATE_NODE(pRoot, pNode, pNode->mKey);
+ KRB_WRITE_UNLOCK(pRoot);
+ }
+
+ return pNode;
+
+#else
+ /*
+ * Delete it, if we got the wrong one, reinsert it.
+ *
+ * This ASSUMS that the caller is NOT going to hand us a lot
+ * of wrong nodes but just uses this API for his convenience.
+ */
+ KRBNODE *pRemovedNode = KRB_FN(Remove)(pRoot, pNode->mKey);
+ if (pRemovedNode == pNode)
+ return pRemovedNode;
+
+ KRB_FN(Insert)(pRoot, pRemovedNode);
+ return NULL;
+#endif
+}
+
diff --git a/src/lib/kStuff/include/k/kRbTmpl/kRbRemoveBestFit.h b/src/lib/kStuff/include/k/kRbTmpl/kRbRemoveBestFit.h
new file mode 100644
index 0000000..17fc66d
--- /dev/null
+++ b/src/lib/kStuff/include/k/kRbTmpl/kRbRemoveBestFit.h
@@ -0,0 +1,70 @@
+/* $Id: kRbRemoveBestFit.h 35 2009-11-08 19:39:03Z bird $ */
+/** @file
+ * kRbTmpl - Templated Red-Black Trees, Remove Best Fitting Node.
+ */
+
+/*
+ * Copyright (c) 1999-2009 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.
+ */
+
+/**
+ * Finds the best fitting node in the tree for the given Key value and removes the node.
+ *
+ * @returns Pointer to the removed node.
+ * @param pRoot Pointer to the Red-Back tree's root structure.
+ * @param Key The Key of which is to be found a best fitting match for..
+ * @param fAbove K_TRUE: Returned node is have the closest key to Key from above.
+ * K_FALSE: Returned node is have the closest key to Key from below.
+ *
+ * @remark This implementation uses GetBestFit and then Remove and might therefore
+ * not be the most optimal kind of implementation, but it reduces the complexity
+ * code size, and the likelyhood for bugs.
+ */
+KRB_DECL(KRBNODE *) KRB_FN(RemoveBestFit)(KRBROOT *pRoot, KRBKEY Key, KBOOL fAbove)
+{
+ /*
+ * If we find anything we'll have to remove the node and return it.
+ * Now, if duplicate keys are allowed we'll remove a duplicate before
+ * removing the in-tree node as this is way cheaper.
+ */
+ KRBNODE *pNode = KRB_FN(GetBestFit)(pRoot, Key, fAbove);
+ if (pNode != NULL)
+ {
+#ifdef KRB_EQUAL_ALLOWED
+ KRB_WRITE_LOCK(pRoot); /** @todo the locking isn't quite sane here. :-/ */
+ if (pNode->mpList != KRB_NULL)
+ {
+ KRBNODE *pRet = KRB_GET_POINTER(&pNode->mpList);
+ KRB_SET_POINTER_NULL(&pNode->mpList, &pRet->mpList);
+ KRB_CACHE_INVALIDATE_NODE(pRoot, pNode, pNode->mKey);
+ KRB_WRITE_UNLOCK(pRoot);
+ return pRet;
+ }
+ KRB_WRITE_UNLOCK(pRoot);
+#endif
+ pNode = KRB_FN(Remove)(pRoot, pNode->mKey);
+ }
+ return pNode;
+}
+
diff --git a/src/lib/kStuff/include/k/kRbTmpl/kRbUndef.h b/src/lib/kStuff/include/k/kRbTmpl/kRbUndef.h
new file mode 100644
index 0000000..793108b
--- /dev/null
+++ b/src/lib/kStuff/include/k/kRbTmpl/kRbUndef.h
@@ -0,0 +1,79 @@
+/* $Id: kRbUndef.h 35 2009-11-08 19:39:03Z bird $ */
+/** @file
+ * kRbTmpl - Undefines All Macros (both config and temp).
+ */
+
+/*
+ * Copyright (c) 2006-2009 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.
+ */
+
+/*
+ * The configuration.
+ */
+#undef KRB_EQUAL_ALLOWED
+#undef KRB_CHECK_FOR_EQUAL_INSERT
+#undef KRB_MAX_STACK
+#undef KRB_RANGE
+#undef KRB_OFFSET
+#undef KRB_STD_KEY_COMP
+#undef KRB_CACHE_SIZE
+#undef KRB_CACHE_HASH
+#undef KRB_LOCKED
+#undef KRB_WRITE_LOCK
+#undef KRB_WRITE_UNLOCK
+#undef KRB_READ_LOCK
+#undef KRB_READ_UNLOCK
+#undef KRBKEY
+#undef KRBNODE
+#undef KRBTREEPTR
+#undef KRBROOT
+#undef KRB_FN
+#undef KRB_TYPE
+#undef KRB_INT
+#undef KRB_DECL
+#undef mKey
+#undef mKeyLast
+#undef mfIsRed
+#undef mpLeft
+#undef mpRight
+#undef mpList
+#undef mpRoot
+#undef maLookthru
+#undef KRB_CMP_G
+#undef KRB_CMP_E
+#undef KRB_CMP_NE
+#undef KRB_R_IS_IDENTICAL
+#undef KRB_R_IS_INTERSECTING
+#undef KRB_R_IS_IN_RANGE
+
+/*
+ * Internal ones.
+ */
+#undef KRB_IS_RED
+#undef KRB_NULL
+#undef KRB_GET_POINTER
+#undef KRB_GET_POINTER_NULL
+#undef KRB_SET_POINTER
+#undef KRB_SET_POINTER_NULL
+
diff --git a/src/lib/kStuff/include/k/kRbU32.h b/src/lib/kStuff/include/k/kRbU32.h
new file mode 100644
index 0000000..3b68b5e
--- /dev/null
+++ b/src/lib/kStuff/include/k/kRbU32.h
@@ -0,0 +1,68 @@
+/* $Id: kRbU32.h 35 2009-11-08 19:39:03Z bird $ */
+/** @file
+ * kRb - Red-Black Tree Implementation, KU32 keys.
+ */
+
+/*
+ * Copyright (c) 2006-2009 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.
+ */
+
+#ifndef ___k_kRbU32_h___
+#define ___k_kRbU32_h___
+
+typedef struct KRBU32
+{
+ KU32 mKey;
+ KBOOL mfRed;
+ struct KRBU32 *mpLeft;
+ struct KRBU32 *mpRight;
+} KRBU32;
+typedef KRBU32 *PRBU32;
+typedef KRBU32 **PPRBU32;
+
+/*#define KRB_EQUAL_ALLOWED*/
+#define KRB_CHECK_FOR_EQUAL_INSERT
+/*#define KRB_RANGE */
+/*#define KRB_OFFSET */
+#define KRB_MAX_STACK 48
+#define KRB_STD_KEY_COMP
+#define KRBKEY KU32
+#define KRBNODE KRBU32
+#define KRB_FN(name) kRbU32 ## name
+#define KRB_TYPE(prefix,name) prefix ## KRBU32 ## name
+#define KRB_INT(name) KRBU32INT ## name
+#define KRB_DECL(rettype) K_DECL_INLINE(rettype)
+
+#include <k/kRbTmpl/kRbBase.h>
+#include <k/kRbTmpl/kRbDoWithAll.h>
+#include <k/kRbTmpl/kRbEnum.h>
+#include <k/kRbTmpl/kRbGet.h>
+#include <k/kRbTmpl/kRbGetBestFit.h>
+#include <k/kRbTmpl/kRbGetWithParent.h>
+#include <k/kRbTmpl/kRbRemove2.h>
+#include <k/kRbTmpl/kRbRemoveBestFit.h>
+#include <k/kRbTmpl/kRbUndef.h>
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kRdr.h b/src/lib/kStuff/include/k/kRdr.h
new file mode 100644
index 0000000..7e0b5e8
--- /dev/null
+++ b/src/lib/kStuff/include/k/kRdr.h
@@ -0,0 +1,86 @@
+/* $Id: kRdr.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kRdr - The File Provider.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___kRdr_h___
+#define ___kRdr_h___
+
+#include <k/kDefs.h>
+#include <k/kTypes.h>
+
+/** @defgroup grp_kRdr kRdr - The File Provider
+ * @{ */
+
+/** @def KRDR_DECL
+ * Declares a kRdr function according to build context.
+ * @param type The return type.
+ */
+#if defined(KRDR_BUILDING_DYNAMIC)
+# define KRDR_DECL(type) K_DECL_EXPORT(type)
+#elif defined(KRDR_BUILT_DYNAMIC)
+# define KRDR_DECL(type) K_DECL_IMPORT(type)
+#else
+# define KRDR_DECL(type) type
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+KRDR_DECL(int) kRdrOpen( PPKRDR ppRdr, const char *pszFilename);
+KRDR_DECL(int) kRdrClose( PKRDR pRdr);
+KRDR_DECL(int) kRdrRead( PKRDR pRdr, void *pvBuf, KSIZE cb, KFOFF off);
+KRDR_DECL(int) kRdrAllMap( PKRDR pRdr, const void **ppvBits);
+KRDR_DECL(int) kRdrAllUnmap( PKRDR pRdr, const void *pvBits);
+KRDR_DECL(KFOFF) kRdrSize( PKRDR pRdr);
+KRDR_DECL(KFOFF) kRdrTell( PKRDR pRdr);
+KRDR_DECL(const char *) kRdrName( PKRDR pRdr);
+KRDR_DECL(KIPTR) kRdrNativeFH( PKRDR pRdr);
+KRDR_DECL(KSIZE) kRdrPageSize( PKRDR pRdr);
+KRDR_DECL(int) kRdrMap( PKRDR pRdr, void **ppvBase, KU32 cSegments, PCKLDRSEG paSegments, KBOOL fFixed);
+KRDR_DECL(int) kRdrRefresh( PKRDR pRdr, void *pvBase, KU32 cSegments, PCKLDRSEG paSegments);
+KRDR_DECL(int) kRdrProtect( PKRDR pRdr, void *pvBase, KU32 cSegments, PCKLDRSEG paSegments, KBOOL fUnprotectOrProtect);
+KRDR_DECL(int) kRdrUnmap( PKRDR pRdr, void *pvBase, KU32 cSegments, PCKLDRSEG paSegments);
+KRDR_DECL(void) kRdrDone( PKRDR pRdr);
+
+KRDR_DECL(int) kRdrBufOpen(PPKRDR ppRdr, const char *pszFilename);
+KRDR_DECL(int) kRdrBufWrap(PPKRDR ppRdr, PKRDR pRdr, KBOOL fCloseIt);
+KRDR_DECL(KBOOL) kRdrBufIsBuffered(PKRDR pRdr);
+KRDR_DECL(int) kRdrBufLine(PKRDR pRdr, char *pszLine, KSIZE cbLine);
+KRDR_DECL(int) kRdrBufLineEx(PKRDR pRdr, char *pszLine, KSIZE *pcbLine);
+KRDR_DECL(const char *) kRdrBufLineQ(PKRDR pRdr);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kRdrAll.h b/src/lib/kStuff/include/k/kRdrAll.h
new file mode 100644
index 0000000..78f946f
--- /dev/null
+++ b/src/lib/kStuff/include/k/kRdrAll.h
@@ -0,0 +1,127 @@
+/* $Id: kRdrAll.h 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kRdr - The File Provider, All Details and Dependencies Included.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef ___k_kRdrAll_h___
+#define ___k_kRdrAll_h___
+
+#include <k/kDefs.h>
+#include <k/kLdr.h>
+#include <k/kRdr.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @defgroup grp_kRdrAll All
+ * @addtogroup grp_kRdr
+ * @{
+ */
+
+/**
+ * File provider instance operations.
+ */
+typedef struct KRDROPS
+{
+ /** The name of this file provider. */
+ const char *pszName;
+ /** Pointer to the next file provider. */
+ const struct KRDROPS *pNext;
+
+ /** Try create a new file provider instance.
+ *
+ * @returns 0 on success, OS specific error code on failure.
+ * @param ppRdr Where to store the file provider instance.
+ * @param pszFilename The filename to open.
+ */
+ int (* pfnCreate)( PPKRDR ppRdr, const char *pszFilename);
+ /** Destroy the file provider instance.
+ *
+ * @returns 0 on success, OS specific error code on failure.
+ * On failure, the file provider instance will be in an indeterminate state - don't touch it!
+ * @param pRdr The file provider instance.
+ */
+ int (* pfnDestroy)( PKRDR pRdr);
+ /** @copydoc kRdrRead */
+ int (* pfnRead)( PKRDR pRdr, void *pvBuf, KSIZE cb, KFOFF off);
+ /** @copydoc kRdrAllMap */
+ int (* pfnAllMap)( PKRDR pRdr, const void **ppvBits);
+ /** @copydoc kRdrAllUnmap */
+ int (* pfnAllUnmap)(PKRDR pRdr, const void *pvBits);
+ /** @copydoc kRdrSize */
+ KFOFF (* pfnSize)( PKRDR pRdr);
+ /** @copydoc kRdrTell */
+ KFOFF (* pfnTell)( PKRDR pRdr);
+ /** @copydoc kRdrName */
+ const char * (* pfnName)(PKRDR pRdr);
+ /** @copydoc kRdrNativeFH */
+ KIPTR (* pfnNativeFH)(PKRDR pRdr);
+ /** @copydoc kRdrPageSize */
+ KSIZE (* pfnPageSize)(PKRDR pRdr);
+ /** @copydoc kRdrMap */
+ int (* pfnMap)( PKRDR pRdr, void **ppvBase, KU32 cSegments, PCKLDRSEG paSegments, KBOOL fFixed);
+ /** @copydoc kRdrRefresh */
+ int (* pfnRefresh)( PKRDR pRdr, void *pvBase, KU32 cSegments, PCKLDRSEG paSegments);
+ /** @copydoc kRdrProtect */
+ int (* pfnProtect)( PKRDR pRdr, void *pvBase, KU32 cSegments, PCKLDRSEG paSegments, KBOOL fUnprotectOrProtect);
+ /** @copydoc kRdrUnmap */
+ int (* pfnUnmap)( PKRDR pRdr, void *pvBase, KU32 cSegments, PCKLDRSEG paSegments);
+ /** @copydoc kRdrDone */
+ void (* pfnDone)( PKRDR pRdr);
+ /** The usual non-zero dummy that makes sure we've initialized all members. */
+ KU32 u32Dummy;
+} KRDROPS;
+/** Pointer to file provider operations. */
+typedef KRDROPS *PKRDROPS;
+/** Pointer to const file provider operations. */
+typedef const KRDROPS *PCKRDROPS;
+
+
+/**
+ * File provider instance core.
+ */
+typedef struct KRDR
+{
+ /** Magic number (KRDR_MAGIC). */
+ KU32 u32Magic;
+ /** Pointer to the file provider operations. */
+ PCKRDROPS pOps;
+} KRDR;
+
+void kRdrAddProvider(PKRDROPS pAdd);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/lib/kStuff/include/k/kTypes.h b/src/lib/kStuff/include/k/kTypes.h
new file mode 100644
index 0000000..c957566
--- /dev/null
+++ b/src/lib/kStuff/include/k/kTypes.h
@@ -0,0 +1,531 @@
+/* $Id: kTypes.h 95 2016-09-26 07:23:08Z bird $ */
+/** @file
+ * kTypes - Typedefs And Related Constants And Macros.
+ */
+
+/*
+ * Copyright (c) 2006-2009 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.
+ */
+
+#ifndef ___k_kTypes_h___
+#define ___k_kTypes_h___
+
+#include <k/kDefs.h>
+
+/** @defgroup grp_kTypes kTypes - Typedefs And Related Constants And Macros
+ * @{
+ */
+
+/** @typedef KI64
+ * 64-bit signed integer. */
+/** @typedef KU64
+ * 64-bit unsigned integer. */
+/** @def KI64_C
+ * 64-bit signed integer constant.
+ * @param c The constant value. */
+/** @def KU64_C
+ * 64-bit unsigned integer constant.
+ * @param c The constant value. */
+/** @def KI64_PRI
+ * 64-bit signed integer printf format. */
+/** @def KU64_PRI
+ * 64-bit unsigned integer printf format. */
+/** @def KX64_PRI
+ * 64-bit signed and unsigned integer hexadecimal printf format. */
+
+/** @typedef KI32
+ * 32-bit signed integer. */
+/** @typedef KU32
+ * 32-bit unsigned integer. */
+/** @def KI32_C
+ * 32-bit signed integer constant.
+ * @param c The constant value. */
+/** @def KU32_C
+ * 32-bit unsigned integer constant.
+ * @param c The constant value. */
+/** @def KI32_PRI
+ * 32-bit signed integer printf format. */
+/** @def KU32_PRI
+ * 32-bit unsigned integer printf format. */
+/** @def KX32_PRI
+ * 32-bit signed and unsigned integer hexadecimal printf format. */
+
+/** @typedef KI16
+ * 16-bit signed integer. */
+/** @typedef KU16
+ * 16-bit unsigned integer. */
+/** @def KI16_C
+ * 16-bit signed integer constant.
+ * @param c The value. */
+/** @def KU16_C
+ * 16-bit unsigned integer constant.
+ * @param c The value. */
+/** @def KI16_PRI
+ * 16-bit signed integer printf format. */
+/** @def KU16_PRI
+ * 16-bit unsigned integer printf format. */
+/** @def KX16_PRI
+ * 16-bit signed and unsigned integer hexadecimal printf format. */
+
+/** @typedef KI8
+ * 8-bit signed integer. */
+/** @typedef KU8
+ * 8-bit unsigned integer. */
+/** @def KI8_C
+ * 8-bit signed integer constant.
+ * @param c The constant value. */
+/** @def KU8_C
+ * 8-bit unsigned integer constant.
+ * @param c The constant value. */
+/** @def KI8_PRI
+ * 8-bit signed integer printf format. */
+/** @def KU8_PRI
+ * 8-bit unsigned integer printf format. */
+/** @def KX8_PRI
+ * 8-bit signed and unsigned integer hexadecimal printf format. */
+
+/** @typedef KSIZE
+ * Memory size type; unsigned integer. */
+/** @typedef KSSIZE
+ * Memory size type; signed integer. */
+/** @def KSIZE_C
+ * Memory size constant.
+ * @param c The constant value. */
+/** @def KSSIZE_C
+ * Memory size constant.
+ * @param c The constant value. */
+/** @def KSIZE_MAX
+ * Memory size max constant.*/
+/** @def KSSIZE_MAX
+ * Memory size max constant.*/
+/** @def KSSIZE_MIN
+ * Memory size min constant.*/
+/** @def KSIZE_PRI
+ * Memory size default printf format (hex). */
+/** @def KSIZE_PRI_U
+ * Memory size unsigned decimal printf format. */
+/** @def KSIZE_PRI_I
+ * Memory size signed decimal printf format. */
+/** @def KSIZE_PRI_X
+ * Memory size hexadecimal printf format. */
+/** @def KSSIZE_PRI
+ * Memory size default printf format (hex). */
+/** @def KSSIZE_PRI_U
+ * Memory size unsigned decimal printf format. */
+/** @def KSSIZE_PRI_I
+ * Memory size signed decimal printf format. */
+/** @def KSSIZE_PRI_X
+ * Memory size hexadecimal printf format. */
+
+/** @typedef KIPTR
+ * Signed integer type capable of containing a pointer value. */
+/** @typedef KUPTR
+ * Unsigned integer type capable of containing a pointer value. */
+/** @def KIPTR_C
+ * Signed pointer constant.
+ * @param c The constant value. */
+/** @def KUPTR_C
+ * Unsigned pointer constant.
+ * @param c The constant value. */
+/** @def KIPTR_MAX
+ * Signed pointer max constant.*/
+/** @def KIPTR_MIN
+ * Signed pointer min constant.*/
+/** @def KUPTR_MAX
+ * Unsigned pointer max constant.*/
+/** @def KIPTR_PRI
+ * Signed pointer printf format. */
+/** @def KUPTR_PRI
+ * Unsigned pointer printf format. */
+
+
+#if K_ARCH_BITS == 32
+ /* ASSUMES int == long == 32-bit, short == 16-bit, char == 8-bit. */
+# ifdef _MSC_VER
+typedef signed __int64 KI64;
+typedef unsigned __int64 KU64;
+#define KI64_PRI "I64d"
+#define KU64_PRI "I64u"
+#define KX64_PRI "I64x"
+# else
+typedef signed long long int KI64;
+typedef unsigned long long int KU64;
+#define KI64_PRI "lld"
+#define KU64_PRI "llu"
+#define KX64_PRI "llx"
+# endif
+typedef signed int KI32;
+typedef unsigned int KU32;
+typedef signed short int KI16;
+typedef unsigned short int KU16;
+typedef signed char KI8;
+typedef unsigned char KU8;
+#define KI64_C(c) (c ## LL)
+#define KU64_C(c) (c ## ULL)
+#define KI32_C(c) (c)
+#define KU32_C(c) (c ## U)
+#define KI16_C(c) (c)
+#define KU16_C(c) (c)
+#define KI8_C(c) (c)
+#define KU8_C(c) (c)
+
+#define KI32_PRI "d"
+#define KU32_PRI "u"
+#define KX32_PRI "x"
+#define KI16_PRI "d"
+#define KU16_PRI "u"
+#define KX16_PRI "x"
+#define KI8_PRI "d"
+#define KU8_PRI "u"
+#define KX8_PRI "x"
+
+typedef KI32 KSSIZE;
+#define KSSIZE(c) KI32_C(c)
+#define KSSIZE_MAX KI32_MAX
+#define KSSIZE_MIN KI32_MIN
+#define KSSIZE_PRI KX32_PRI
+
+typedef KU32 KSIZE;
+#define KSIZE_C(c) KU32_C(c)
+#define KSIZE_MAX KU32_MAX
+#define KSIZE_PRI KX32_PRI
+#define KSIZE_PRI_U KU32_PRI
+#define KSIZE_PRI_I KI32_PRI
+#define KSIZE_PRI_X KX32_PRI
+#define KIPTR_C(c) KI32_C(c)
+
+typedef KI32 KIPTR;
+#define KIPTR_MAX KI32_MAX
+#define KIPTR_MIN KI32_MIN
+#define KIPTR_PRI KX32_PRI
+
+typedef KU32 KUPTR;
+#define KUPTR_C(c) KU32_C(c)
+#define KUPTR_MAX KU32_MAX
+#define KUPTR_PRI KX32_PRI
+
+
+#elif K_ARCH_BITS == 64
+
+# if K_OS == K_OS_WINDOWS
+# if _MSC_VER
+typedef signed __int64 KI64;
+typedef unsigned __int64 KU64;
+# define KI64_PRI "I64d"
+# define KU64_PRI "I64u"
+# define KX64_PRI "I64x"
+# else
+typedef signed long long int KI64;
+typedef unsigned long long int KU64;
+# define KI64_PRI "lld"
+# define KU64_PRI "llu"
+# define KX64_PRI "llx"
+# endif
+# define KI64_C(c) (c ## LL)
+# define KU64_C(c) (c ## ULL)
+# else
+typedef signed long int KI64;
+typedef unsigned long int KU64;
+# define KI64_C(c) (c ## L)
+# define KU64_C(c) (c ## UL)
+# define KI64_PRI "ld"
+# define KU64_PRI "lu"
+# define KX64_PRI "lx"
+# endif
+typedef signed int KI32;
+typedef unsigned int KU32;
+typedef signed short KI16;
+typedef unsigned short KU16;
+typedef signed char KI8;
+typedef unsigned char KU8;
+#define KI32_C(c) (c)
+#define KU32_C(c) (c ## U)
+#define KI16_C(c) (c)
+#define KU16_C(c) (c)
+#define KI8_C(c) (c)
+#define KU8_C(c) (c)
+
+#define KI32_PRI "d"
+#define KU32_PRI "u"
+#define KX32_PRI "x"
+#define KI16_PRI "d"
+#define KU16_PRI "u"
+#define KX16_PRI "x"
+#define KI8_PRI "d"
+#define KU8_PRI "u"
+#define KX8_PRI "x"
+
+typedef KI64 KSSIZE;
+#define KSSIZE(c) KI64_C(c)
+#define KSSIZE_MAX KI64_MAX
+#define KSSIZE_MIN KI64_MIN
+#define KSSIZE_PRI KX64_PRI
+#define KSSIZE_PRI_U KU64_PRI
+#define KSSIZE_PRI_I KI64_PRI
+#define KSSIZE_PRI_X KX64_PRI
+
+typedef KU64 KSIZE;
+#define KSIZE_C(c) KU64_C(c)
+#define KSIZE_MAX KU64_MAX
+#define KSIZE_PRI_U KU64_PRI
+#define KSIZE_PRI_I KI64_PRI
+#define KSIZE_PRI_X KX64_PRI
+#define KSIZE_PRI KX64_PRI
+
+typedef KI64 KIPTR;
+#define KIPTR_C(c) KI64_C(c)
+#define KIPTR_MAX KI64_MAX
+#define KIPTR_MIN KI64_MIN
+#define KIPTR_PRI KX64_PRI
+
+typedef KU64 KUPTR;
+#define KUPTR_C(c) KU64_C(c)
+#define KUPTR_MAX KU64_MAX
+#define KUPTR_PRI KX64_PRI
+
+#else
+# error "Port Me"
+#endif
+
+
+/** Min KI8 value. */
+#define KI8_MIN (KI8_C(-0x7f) - 1)
+/** Min KI16 value. */
+#define KI16_MIN (KI16_C(-0x7fff) - 1)
+/** Min KI32 value. */
+#define KI32_MIN (KI32_C(-0x7fffffff) - 1)
+/** Min KI64 value. */
+#define KI64_MIN (KI64_C(-0x7fffffffffffffff) - 1)
+/** Max KI8 value. */
+#define KI8_MAX KI8_C(0x7f)
+/** Max KI16 value. */
+#define KI16_MAX KI16_C(0x7fff)
+/** Max KI32 value. */
+#define KI32_MAX KI32_C(0x7fffffff)
+/** Max KI64 value. */
+#define KI64_MAX KI64_C(0x7fffffffffffffff)
+/** Max KU8 value. */
+#define KU8_MAX KU8_C(0xff)
+/** Max KU16 value. */
+#define KU16_MAX KU16_C(0xffff)
+/** Max KU32 value. */
+#define KU32_MAX KU32_C(0xffffffff)
+/** Max KU64 value. */
+#define KU64_MAX KU64_C(0xffffffffffffffff)
+
+/** File offset. */
+typedef KI64 KFOFF;
+/** Pointer a file offset. */
+typedef KFOFF *PFOFF;
+/** Pointer a const file offset. */
+typedef KFOFF *PCFOFF;
+/** The min value for the KFOFF type. */
+#define KFOFF_MIN KI64_MIN
+/** The max value for the KFOFF type. */
+#define KFOFF_MAX KI64_MAX
+/** File offset contstant.
+ * @param c The constant value. */
+#define KFOFF_C(c) KI64_C(c)
+/** File offset printf format. */
+#define KFOFF_PRI KI64_PRI
+
+
+/**
+ * Memory Protection.
+ */
+typedef enum KPROT
+{
+ /** The usual invalid 0. */
+ KPROT_INVALID = 0,
+ /** No access (page not present). */
+ KPROT_NOACCESS,
+ /** Read only. */
+ KPROT_READONLY,
+ /** Read & write. */
+ KPROT_READWRITE,
+ /** Read & copy on write. */
+ KPROT_WRITECOPY,
+ /** Execute only. */
+ KPROT_EXECUTE,
+ /** Execute & read. */
+ KPROT_EXECUTE_READ,
+ /** Execute, read & write. */
+ KPROT_EXECUTE_READWRITE,
+ /** Execute, read & copy on write. */
+ KPROT_EXECUTE_WRITECOPY,
+ /** The usual end value. (exclusive) */
+ KPROT_END,
+ /** Blow the type up to 32-bits. */
+ KPROT_32BIT_HACK = 0x7fffffff
+} KPROT;
+/** Pointer to a memory protection enum. */
+typedef KPROT *PKPROT;
+/** Pointer to a const memory protection enum. */
+typedef KPROT const *PCKPROT;
+
+/** Boolean.
+ * This can be used as a tri-state type, but then you *must* do == checks. */
+typedef KI8 KBOOL;
+/** Pointer to a boolean value. */
+typedef KBOOL *PKBOOL;
+/** Pointer to a const boolean value. */
+typedef KBOOL const *PCKBOOL;
+/** Maxium value the KBOOL type can hold (officially). */
+#define KBOOL_MIN KI8_C(-1)
+/** Maxium value the KBOOL type can hold (officially). */
+#define KBOOL_MAX KI8_C(1)
+/** The KBOOL printf format. */
+#define KBOOL_PRI KU8_PRI
+/** Boolean true constant. */
+#define K_TRUE KI8_C(1)
+/** Boolean false constant. */
+#define K_FALSE KI8_C(0)
+/** Boolean unknown constant (the third state). */
+#define K_UNKNOWN KI8_C(-1)
+
+
+/**
+ * Integer union.
+ */
+typedef union KUINT
+{
+ KFOFF iBig; /**< The biggest member. */
+ KBOOL fBool; /**< Boolean. */
+ KU8 b; /**< unsigned 8-bit. */
+ KU8 u8; /**< unsigned 8-bit. */
+ KI8 i8; /**< signed 8-bit. */
+ KU16 u16; /**< unsigned 16-bit. */
+ KI16 i16; /**< signed 16-bit. */
+ KU32 u32; /**< unsigned 32-bit. */
+ KI32 i32; /**< signed 32-bit. */
+ KU64 u64; /**< unsigned 64-bit. */
+ KI64 i64; /**< signed 64-bit. */
+ KSIZE cbUnsign; /**< unsigned size. */
+ KSSIZE cbSign; /**< signed size. */
+ KFOFF offFile; /**< file offset. */
+ KUPTR uPtr; /**< unsigned pointer. */
+ KIPTR iPtr; /**< signed pointer. */
+ void *pv; /**< void pointer. */
+ char ch; /**< char. */
+ unsigned char uch; /**< unsigned char. */
+ signed char chSigned; /**< signed char. */
+ unsigned short uShort; /**< Unsigned short. */
+ signed short iShort; /**< Signed short. */
+ unsigned int uInt; /**< Unsigned int. */
+ signed int iInt; /**< Signed int. */
+ unsigned long uLong; /**< Unsigned long. */
+ signed long iLong; /**< Signed long. */
+} KUINT;
+
+
+/**
+ * Integer pointer union.
+ */
+typedef union KPUINT
+{
+ KFOFF *piBig; /**< The biggest member. */
+ KBOOL *pfBool; /**< Boolean. */
+ KU8 *pb; /**< unsigned 8-bit. */
+ KU8 *pu8; /**< unsigned 8-bit. */
+ KI8 *pi8; /**< signed 8-bit. */
+ KU16 *pu16; /**< unsigned 16-bit. */
+ KI16 *pi16; /**< signed 16-bit. */
+ KU32 *pu32; /**< unsigned 32-bit. */
+ KI32 *pi32; /**< signed 32-bit. */
+ KU64 *pu64; /**< unsigned 64-bit. */
+ KI64 *pi64; /**< signed 64-bit. */
+ KSIZE *pcbUnsign; /**< unsigned size. */
+ KSSIZE *pcbSign; /**< signed size. */
+ KFOFF *poffFile; /**< file offset. */
+ KUPTR *puPtr; /**< unsigned pointer. */
+ KIPTR *piPtr; /**< signed pointer. */
+ void **ppv; /**< void pointer pointer. */
+ void *pv; /**< void pointer. */
+ char *pch; /**< char. */
+ char *psz; /**< zero terminated string. */
+ unsigned char *puch; /**< unsigned char. */
+ signed char *pchSigned; /**< signed char. */
+ unsigned short *puShort; /**< Unsigned short. */
+ signed short *piShort; /**< Signed short. */
+ unsigned int *puInt; /**< Unsigned int. */
+ signed int *piInt; /**< Signed int. */
+ unsigned long *puLong; /**< Unsigned long. */
+ signed long *piLong; /**< Signed long. */
+} KPUINT;
+
+/**
+ * Integer const pointer union.
+ */
+typedef union KPCUINT
+{
+ KFOFF const *piBig; /**< The biggest member. */
+ KBOOL const *pfBool; /**< Boolean. */
+ KU8 const *pb; /**< byte. */
+ KU8 const *pu8; /**< unsigned 8-bit. */
+ KI8 const *pi8; /**< signed 8-bit. */
+ KU16 const *pu16; /**< unsigned 16-bit. */
+ KI16 const *pi16; /**< signed 16-bit. */
+ KU32 const *pu32; /**< unsigned 32-bit. */
+ KI32 const *pi32; /**< signed 32-bit. */
+ KU64 const *pu64; /**< unsigned 64-bit. */
+ KI64 const *pi64; /**< signed 64-bit. */
+ KSIZE const *pcbUnsign; /**< unsigned size. */
+ KSSIZE const *pcbSign; /**< signed size. */
+ KFOFF const *poffFile; /**< file offset. */
+ KUPTR const *puPtr; /**< unsigned pointer. */
+ KIPTR const *piPtr; /**< signed pointer. */
+ void const **ppv; /**< void pointer pointer. */
+ void const *pv; /**< void pointer. */
+ char const *pch; /**< char. */
+ char const *psz; /**< zero terminated string. */
+ unsigned char const *puch; /**< unsigned char. */
+ signed char const *pchSigned; /**< signed char. */
+ unsigned short const *puShort; /**< Unsigned short. */
+ signed short const *piShort; /**< Signed short. */
+ unsigned int const *puInt; /**< Unsigned int. */
+ signed int const *piInt; /**< Signed int. */
+ unsigned long const *puLong; /**< Unsigned long. */
+ signed long const *piLong; /**< Signed long. */
+} KPCUINT;
+
+
+/** @name Forward Declarations / Handle Types.
+ * @{ */
+
+/** Pointer to a file provider instance. */
+typedef struct KRDR *PKRDR;
+/** Pointer to a file provider instance pointer. */
+typedef struct KRDR **PPKRDR;
+
+/** Pointer to a loader segment. */
+typedef struct KLDRSEG *PKLDRSEG;
+/** Pointer to a loader segment. */
+typedef const struct KLDRSEG *PCKLDRSEG;
+
+/** @} */
+
+/** @} */
+
+#endif
+