[rtems commit] cpukit: Add libdl with the Runtime Loader (RTL) code.

Chris Johns chrisj at rtems.org
Fri Oct 31 00:19:20 UTC 2014


Module:    rtems
Branch:    master
Commit:    ae5fe7e6bca2874c5f1ef077204bb63124fb3db3
Changeset: http://git.rtems.org/rtems/commit/?id=ae5fe7e6bca2874c5f1ef077204bb63124fb3db3

Author:    Chris Johns <chrisj at rtems.org>
Date:      Sun Oct 26 18:09:41 2014 -0700

cpukit: Add libdl with the Runtime Loader (RTL) code.

This is a merge of the RTL project.

---

 cpukit/Makefile.am                                 |   20 +-
 cpukit/configure.ac                                |   18 +-
 cpukit/libdl/Makefile.am                           |   36 +
 cpukit/libdl/dlfcn-shell.c                         |  117 +++
 cpukit/libdl/dlfcn-shell.h                         |   17 +
 cpukit/libdl/dlfcn.c                               |  153 +++
 cpukit/libdl/dlfcn.h                               |  112 ++
 cpukit/libdl/fastlz.c                              |  551 ++++++++++
 cpukit/libdl/fastlz.h                              |  100 ++
 .../libdl/include/arch/arm/machine/elf_machdep.h   |  131 +++
 .../libdl/include/arch/bfin/machine/elf_machdep.h  |   28 +
 .../libdl/include/arch/h8300/machine/elf_machdep.h |   59 ++
 .../libdl/include/arch/i386/machine/elf_machdep.h  |   63 ++
 .../libdl/include/arch/lm32/machine/elf_machdep.h  |   34 +
 .../libdl/include/arch/m32r/machine/elf_machdep.h  |   39 +
 .../libdl/include/arch/m68k/machine/elf_machdep.h  |   47 +
 .../libdl/include/arch/mips/machine/elf_machdep.h  |  196 ++++
 .../libdl/include/arch/moxie/machine/elf_machdep.h |   15 +
 .../libdl/include/arch/nios2/machine/elf_machdep.h |   46 +
 .../include/arch/powerpc/machine/elf_machdep.h     |  105 ++
 .../libdl/include/arch/sparc/machine/elf_machdep.h |   92 ++
 .../libdl/include/arch/v850/machine/elf_machdep.h  |   74 ++
 cpukit/libdl/include/link.h                        |   45 +
 cpukit/libdl/include/link_elf.h                    |   79 ++
 cpukit/libdl/include/sys/cdefs_elf.h               |  152 +++
 cpukit/libdl/include/sys/exec_elf.h                | 1097 ++++++++++++++++++++
 cpukit/libdl/preinstall.am                         |    7 +
 cpukit/libdl/rap-shell.c                           |  106 ++
 cpukit/libdl/rap-shell.h                           |   14 +
 cpukit/libdl/rap.c                                 |  484 +++++++++
 cpukit/libdl/rap.h                                 |  115 ++
 cpukit/libdl/rtl-alloc-heap.c                      |   33 +
 cpukit/libdl/rtl-alloc-heap.h                      |   47 +
 cpukit/libdl/rtl-allocator.c                       |  210 ++++
 cpukit/libdl/rtl-allocator.h                       |  176 ++++
 cpukit/libdl/rtl-chain-iterator.c                  |   57 +
 cpukit/libdl/rtl-chain-iterator.h                  |   59 ++
 cpukit/libdl/rtl-debugger.c                        |   96 ++
 cpukit/libdl/rtl-elf.c                             |  882 ++++++++++++++++
 cpukit/libdl/rtl-elf.h                             |  165 +++
 cpukit/libdl/rtl-error.c                           |   47 +
 cpukit/libdl/rtl-error.h                           |   44 +
 cpukit/libdl/rtl-find-file.c                       |  110 ++
 cpukit/libdl/rtl-find-file.h                       |   45 +
 cpukit/libdl/rtl-fwd.h                             |   33 +
 cpukit/libdl/rtl-indirect-ptr.h                    |  235 +++++
 cpukit/libdl/rtl-mdreloc-arm.c                     |  323 ++++++
 cpukit/libdl/rtl-mdreloc-bfin.c                    |  115 ++
 cpukit/libdl/rtl-mdreloc-h8300.c                   |  101 ++
 cpukit/libdl/rtl-mdreloc-i386.c                    |  103 ++
 cpukit/libdl/rtl-mdreloc-lm32.c                    |  120 +++
 cpukit/libdl/rtl-mdreloc-m32r.c                    |  156 +++
 cpukit/libdl/rtl-mdreloc-m68k.c                    |  148 +++
 cpukit/libdl/rtl-mdreloc-mips.c                    |  190 ++++
 cpukit/libdl/rtl-mdreloc-moxie.c                   |   88 ++
 cpukit/libdl/rtl-mdreloc-nios2.c                   |   44 +
 cpukit/libdl/rtl-mdreloc-powerpc.c                 |  186 ++++
 cpukit/libdl/rtl-mdreloc-sparc.c                   |  261 +++++
 cpukit/libdl/rtl-mdreloc-v850.c                    |   97 ++
 cpukit/libdl/rtl-obj-cache.c                       |  197 ++++
 cpukit/libdl/rtl-obj-cache.h                       |  132 +++
 cpukit/libdl/rtl-obj-comp.c                        |  179 ++++
 cpukit/libdl/rtl-obj-comp.h                        |  122 +++
 cpukit/libdl/rtl-obj-fwd.h                         |   39 +
 cpukit/libdl/rtl-obj.c                             | 1031 ++++++++++++++++++
 cpukit/libdl/rtl-obj.h                             |  580 +++++++++++
 cpukit/libdl/rtl-rap.c                             |  980 +++++++++++++++++
 cpukit/libdl/rtl-rap.h                             |   54 +
 cpukit/libdl/rtl-shell.c                           |  389 +++++++
 cpukit/libdl/rtl-shell.h                           |   39 +
 cpukit/libdl/rtl-string.c                          |   32 +
 cpukit/libdl/rtl-string.h                          |   37 +
 cpukit/libdl/rtl-sym.c                             |  245 +++++
 cpukit/libdl/rtl-sym.h                             |  128 +++
 cpukit/libdl/rtl-trace.c                           |  134 +++
 cpukit/libdl/rtl-trace.h                           |  100 ++
 cpukit/libdl/rtl-unresolved.c                      |  471 +++++++++
 cpukit/libdl/rtl-unresolved.h                      |  212 ++++
 cpukit/libdl/rtl.c                                 |  637 ++++++++++++
 cpukit/libdl/rtl.h                                 |  320 ++++++
 cpukit/preinstall.am                               |   87 ++-
 cpukit/wrapup/Makefile.am                          |    4 +
 testsuites/libtests/Makefile.am                    |    6 +-
 testsuites/libtests/configure.ac                   |   24 +
 testsuites/libtests/dl01/Makefile.am               |   43 +
 testsuites/libtests/dl01/dl-load.c                 |   77 ++
 testsuites/libtests/dl01/dl-load.h                 |   14 +
 testsuites/libtests/dl01/dl-o1.c                   |   31 +
 testsuites/libtests/dl01/init.c                    |   84 ++
 89 files changed, 14746 insertions(+), 5 deletions(-)

diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am
index 93b07c8..5e0ae72 100644
--- a/cpukit/Makefile.am
+++ b/cpukit/Makefile.am
@@ -11,6 +11,7 @@ SUBDIRS += libi2c
 SUBDIRS += libmisc
 SUBDIRS += libmd
 SUBDIRS += libgnat
+SUBDIRS += libdl
 SUBDIRS += wrapup
 
 SUBDIRS += zlib
@@ -41,7 +42,6 @@ include_uuid_HEADERS = libmisc/uuid/uuid.h
 include_utf8procdir = $(includedir)/utf8proc
 include_utf8proc_HEADERS = libmisc/utf8proc/utf8proc.h
 
-if NEWLIB
 include_sysdir = $(includedir)/sys
 include_sys_HEADERS =
 
@@ -69,6 +69,24 @@ include_rtems_bsdnetdir = $(includedir)/rtems/bsdnet
 include_rtems_bsdnet_HEADERS = libnetworking/rtems/bsdnet/servers.h
 include_rtems_bsdnet_HEADERS += libnetworking/rtems/bsdnet/_types.h
 endif
+
+if LIBDL
+include_HEADERS += libdl/dlfcn.h
+include_HEADERS += libdl/include/link.h
+include_HEADERS += libdl/include/link_elf.h
+include_sys_HEADERS += libdl/include/sys/cdefs_elf.h
+include_sys_HEADERS += libdl/include/sys/exec_elf.h
+include_arch_machinedir = $(includedir)/machine
+include_arch_machine_HEADERS =
+include_arch_machine_HEADERS += libdl/include/arch/@RTEMS_CPU@/machine/elf_machdep.h
+include_rtems_rtldir = $(includedir)/rtems/rtl
+include_rtems_rtl_HEADERS =
+include_rtems_rtl_HEADERS += libdl/dlfcn-shell.h
+include_rtems_rtl_HEADERS += libdl/rtl.h libdl/rtl-allocator.h libdl/rtl-obj-fwd.h
+include_rtems_rtl_HEADERS += libdl/rtl-fwd.h libdl/rtl-obj.h libdl/rtl-obj-cache.h
+include_rtems_rtl_HEADERS += libdl/rtl-obj-comp.h libdl/rtl-unresolved.h
+include_rtems_rtl_HEADERS += libdl/rtl-indirect-ptr.h libdl/rtl-sym.h
+include_rtems_rtl_HEADERS += libdl/rap.h libdl/rap-shell.h
 endif
 
 include_rtems_HEADERS += include/rtems/bspIo.h
diff --git a/cpukit/configure.ac b/cpukit/configure.ac
index fcf3437..b3c818c 100644
--- a/cpukit/configure.ac
+++ b/cpukit/configure.ac
@@ -298,7 +298,7 @@ AC_ENABLE_MULTILIB([Makefile],[..])
 AC_MSG_CHECKING([for assignable stdio])
 AC_COMPILE_IFELSE(
   [AC_LANG_PROGRAM(
-    [#include <stdio.h>], 
+    [#include <stdio.h>],
     [stdin = fopen("/tmp", "r")])],
   [HAVE_ASSIGNABLE_STDIO=yes],
   [HAVE_ASSIGNABLE_STDIO=no])
@@ -322,7 +322,7 @@ AC_CHECK_SIZEOF([time_t])
 
 AC_CHECK_SIZEOF([size_t])
 
-# FIXME: Mandatory in SUSv4, optional in SUSv3. 
+# FIXME: Mandatory in SUSv4, optional in SUSv3.
 #   Not implemented in GCC/newlib, so far.
 AC_CHECK_DECLS([WORD_BIT],,,[#include <limits.h>])
 AC_CHECK_DECLS([LONG_BIT],,,[#include <limits.h>])
@@ -372,6 +372,19 @@ AM_CONDITIONAL([RPCTOOLS],[test "$RPCGEN" = rpcgen \
 && test -n "$AWK" \
 && test "$enable_rpcgen" = yes])
 
+# Filter dynamic loading to only build for architectures that have
+# reloc backends
+AC_MSG_CHECKING([whether CPU supports libdl])
+case $RTEMS_CPU in
+  arm | bfin | h8300 | i386 | lm32 | m32r | m68k | mips | \
+  moxie | nios2 | powerpc | sparc | v850)
+   HAVE_LIBDL=yes ;;
+  *)
+   HAVE_LIBDL=no ;;
+esac
+AM_CONDITIONAL(LIBDL,[test x"$HAVE_LIBDL" = x"yes"])
+AC_MSG_RESULT([$HAVE_LIBDL])
+
 RTEMS_AMPOLISH3
 
 # Explicitly list all Makefiles here
@@ -412,6 +425,7 @@ librpc/Makefile
 libmisc/Makefile
 libi2c/Makefile
 libmd/Makefile
+libdl/Makefile
 zlib/Makefile
 ftpd/Makefile
 telnetd/Makefile
diff --git a/cpukit/libdl/Makefile.am b/cpukit/libdl/Makefile.am
new file mode 100644
index 0000000..11f1478
--- /dev/null
+++ b/cpukit/libdl/Makefile.am
@@ -0,0 +1,36 @@
+if LIBDL
+
+include $(top_srcdir)/automake/compile.am
+
+noinst_LIBRARIES = libdl.a
+libdl_a_SOURCES = \
+  dlfcn-shell.c \
+  dlfcn.c \
+  fastlz.c \
+  rap-shell.c \
+  rap.c \
+  rtl.c \
+  rtl-alloc-heap.c \
+  rtl-allocator.c \
+  rtl-chain-iterator.c \
+  rtl-debugger.c \
+  rtl-elf.c \
+  rtl-error.c \
+  rtl-find-file.c \
+  rtl-obj-cache.c \
+  rtl-obj-comp.c \
+  rtl-obj.c \
+  rtl-rap.c \
+  rtl-shell.c \
+  rtl-string.c \
+  rtl-sym.c \
+  rtl-trace.c \
+  rtl-unresolved.c
+
+libdl_a_SOURCES += rtl-mdreloc- at RTEMS_CPU@.c
+libdl_a_CPPFLAGS = $(AM_CPPFLAGS) -DRTEMS_RTL_RAP_LOADER=1 -DRTEMS_RTL_ELF_LOADER=1
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
+
+endif
diff --git a/cpukit/libdl/dlfcn-shell.c b/cpukit/libdl/dlfcn-shell.c
new file mode 100644
index 0000000..5655ab1
--- /dev/null
+++ b/cpukit/libdl/dlfcn-shell.c
@@ -0,0 +1,117 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtld
+ *
+ * @brief RTEMS Run-Time Link Editor Dynamic Loading API Shell Support.
+ *
+ * Shell command wrappers for the Dynamic Loading API.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <dlfcn.h>
+#include <rtems/rtl/dlfcn-shell.h>
+
+static void*
+convert_ascii_to_voidp (const char* arg)
+{
+  if (strcmp (arg, "base") == 0)
+    return RTLD_DEFAULT;
+  return (void*) strtoul (arg, NULL, 16);
+}
+
+int
+shell_dlopen (int argc, char* argv[])
+{
+  int arg;
+  for (arg = 1; arg < argc; arg++)
+  {
+    void* handle = dlopen (argv[arg], RTLD_NOW | RTLD_GLOBAL);
+    if (handle)
+    {
+      int   unresolved;
+      char* message = "loaded";
+      if (dlinfo (handle, RTLD_DI_UNRESOLVED, &unresolved) < 0)
+        message = "dlinfo error checking unresolved status";
+      else if (unresolved)
+        message = "has unresolved externals";
+      printf ("handle: %p %s\n", handle, message);
+    }
+    else
+      printf ("error: %s\n", dlerror ());
+  }
+  return 0;
+}
+
+int
+shell_dlclose (int argc, char* argv[])
+{
+  return 0;
+}
+
+static bool
+lookup_dlsym (void** value, int argc, char* argv[])
+{
+  if (argc >= 3)
+  {
+    void* handle = convert_ascii_to_voidp (argv[1]);
+    if (handle)
+    {
+      *value = dlsym (handle, argv[2]);
+      if (*value)
+        return true;
+      else
+        printf ("error: invalid handle or symbol\n");
+    }
+    else
+      printf ("error: invalid handle");
+  }
+  else
+    printf ("error: requires handle and symbol name\n");
+  return false;
+}
+
+int
+shell_dlsym (int argc, char* argv[])
+{
+  void* value;
+  if (lookup_dlsym (&value, argc, argv))
+  {
+    printf ("%s = %p\n", argv[2], value);
+    return 0;
+  }
+  return -1;
+}
+
+typedef int (*call_t)(int argc, char* argv[]);
+
+int
+shell_dlcall (int argc, char* argv[])
+{
+  void* value;
+  if (lookup_dlsym (&value, argc, argv))
+  {
+    call_t call = value;
+    int    r;
+    printf ("(*%p)(%d, ....)\n", value, argc - 3);
+    r = call (argc - 3, argv + 3);
+    printf ("return %d\n", r);
+    return 0;
+  }
+  return -1;
+}
diff --git a/cpukit/libdl/dlfcn-shell.h b/cpukit/libdl/dlfcn-shell.h
new file mode 100644
index 0000000..0406b6c
--- /dev/null
+++ b/cpukit/libdl/dlfcn-shell.h
@@ -0,0 +1,17 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+
+#if !defined(_DLFCN_SHELL_H_)
+#define _DLFCN_SHELL_H_
+
+int shell_dlopen (int argc, char* argv[]);
+int shell_dlclose (int argc, char* argv[]);
+int shell_dlsym (int argc, char* argv[]);
+int shell_dlcall (int argc, char* argv[]);
+
+#endif
diff --git a/cpukit/libdl/dlfcn.c b/cpukit/libdl/dlfcn.c
new file mode 100644
index 0000000..7c10202
--- /dev/null
+++ b/cpukit/libdl/dlfcn.c
@@ -0,0 +1,153 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtl
+ *
+ * @brief RTEMS POSIX Dynamic Module Loading Interface.
+ *
+ * This is the POSIX interface to run-time loading of code into RTEMS.
+ */
+
+#include <stdint.h>
+#include <dlfcn.h>
+#include <rtems/rtl/rtl.h>
+
+static rtems_rtl_obj_t*
+dl_get_obj_from_handle (void* handle)
+{
+  rtems_rtl_obj_t* obj;
+
+  /*
+   * Handle the special cases provided in NetBSD and Sun documentation.
+   *   http://download.oracle.com/docs/cd/E19253-01/816-5168/dlsym-3c/index.html
+   * We currently do not manage the loading dependences in the module mappings
+   * so we cannot handle the searching based on loading order where overriding
+   * can occur.
+   */
+
+  if ((handle == RTLD_DEFAULT) || (handle == RTLD_SELF))
+    obj = rtems_rtl_baseimage ();
+  else
+    obj = rtems_rtl_check_handle (handle);
+
+  return obj;
+}
+
+void*
+dlopen (const char* name, int mode)
+{
+  rtems_rtl_obj_t* obj = NULL;
+
+  if (!rtems_rtl_lock ())
+    return NULL;
+
+  _rtld_debug.r_state = RT_ADD;
+  _rtld_debug_state ();
+
+  if (name)
+    obj = rtems_rtl_load_object (name, mode);
+  else
+    obj = rtems_rtl_baseimage ();
+
+  _rtld_debug.r_state = RT_CONSISTENT;
+  _rtld_debug_state();
+
+  rtems_rtl_unlock ();
+
+  return obj;
+}
+
+int
+dlclose (void* handle)
+{
+  rtems_rtl_obj_t* obj;
+  int              r;
+
+  if (!rtems_rtl_lock ())
+    return -1;
+
+  obj = rtems_rtl_check_handle (handle);
+  if (!obj)
+  {
+    rtems_rtl_unlock ();
+    return -1;
+  }
+
+  _rtld_debug.r_state = RT_DELETE;
+  _rtld_debug_state ();
+
+  r = rtems_rtl_unload_object (obj) ? 0 : -1;
+
+  _rtld_debug.r_state = RT_CONSISTENT;
+  _rtld_debug_state ();
+
+  rtems_rtl_unlock ();
+
+  return r;
+}
+
+void*
+dlsym (void* handle, const char *symbol)
+{
+  rtems_rtl_obj_t*     obj;
+  rtems_rtl_obj_sym_t* sym;
+  void*                symval = NULL;
+
+  if (!rtems_rtl_lock ())
+    return NULL;
+
+  obj = dl_get_obj_from_handle (handle);
+  if (obj)
+  {
+    sym = rtems_rtl_symbol_obj_find (obj, symbol);
+    if (sym)
+      symval = sym->value;
+  }
+
+  rtems_rtl_unlock ();
+
+  return symval;
+}
+
+const char*
+dlerror (void)
+{
+  static char msg[64];
+  rtems_rtl_get_error (msg, sizeof (msg));
+	return msg;
+}
+
+int
+dlinfo (void* handle, int request, void* p)
+{
+  rtems_rtl_obj_t* obj;
+  int              rc = -1;
+
+  if (!rtems_rtl_lock () || !p)
+    return -1;
+
+  obj = dl_get_obj_from_handle (handle);
+  if (obj)
+  {
+    switch (request)
+    {
+      case RTLD_DI_UNRESOLVED:
+        *((int*) p) = rtems_rtl_obj_unresolved (obj) ? 1 : 0;
+        rc = 0;
+        break;
+      default:
+        break;
+    }
+  }
+
+  rtems_rtl_unlock ();
+
+  return rc;
+}
diff --git a/cpukit/libdl/dlfcn.h b/cpukit/libdl/dlfcn.h
new file mode 100644
index 0000000..1ac3ba1
--- /dev/null
+++ b/cpukit/libdl/dlfcn.h
@@ -0,0 +1,112 @@
+/*	$NetBSD: dlfcn.h,v 1.21 2010/01/07 07:35:35 skrll Exp $	*/
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Paul Kranenburg.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DLFCN_H_
+#define _DLFCN_H_
+
+//#include <sys/featuretest.h>
+#include <sys/cdefs.h>
+
+#if defined(_NETBSD_SOURCE)
+typedef struct _dl_info {
+	const char	*dli_fname;	/* File defining the symbol */
+	void		*dli_fbase;	/* Base address */
+	const char	*dli_sname;	/* Symbol name */
+	const void	*dli_saddr;	/* Symbol address */
+} Dl_info;
+#endif /* defined(_NETBSD_SOURCE) */
+
+/*
+ * User interface to the run-time linker.
+ */
+__BEGIN_DECLS
+void	*dlopen(const char *, int);
+int	dlclose(void *);
+void	*dlsym(void * __restrict, const char * __restrict);
+#if defined(_NETBSD_SOURCE)
+int	dladdr(void * __restrict, Dl_info * __restrict);
+int	dlctl(void *, int, void *);
+#endif
+int	dlinfo(void *, int, void *);
+const char *dlerror(void);
+__END_DECLS
+
+/* Values for dlopen `mode'. */
+#define RTLD_LAZY	1
+#define RTLD_NOW	2
+#define RTLD_GLOBAL	0x100		/* Allow global searches in object */
+#define RTLD_LOCAL	0x200
+#if defined(_NETBSD_SOURCE)
+#define DL_LAZY		RTLD_LAZY	/* Compat */
+#endif
+
+/*
+ * Special handle arguments for dlsym().
+ */
+#define	RTLD_NEXT	((void *) -1)	/* Search subsequent objects. */
+#define	RTLD_DEFAULT	((void *) -2)	/* Use default search algorithm. */
+#define	RTLD_SELF	((void *) -3)	/* Search the caller itself. */
+
+/*
+ * dlctl() commands
+ */
+#if defined(_NETBSD_SOURCE)
+#define DL_GETERRNO	1
+#define DL_GETSYMBOL	2
+#if 0
+#define DL_SETSRCHPATH	x
+#define DL_GETLIST	x
+#define DL_GETREFCNT	x
+#define DL_GETLOADADDR	x
+#endif /* 0 */
+#endif /* defined(_NETBSD_SOURCE) */
+
+/*
+ * dlinfo() commands
+ *
+ * From Solaris: http://docs.sun.com/app/docs/doc/816-5168/dlinfo-3c?a=view
+ */
+#define RTLD_DI_UNRESOLVED 	10
+#if defined(_NETBSD_SOURCE)
+#define RTLD_DI_LINKMAP		3
+#if 0
+#define RTLD_DI_ARGSINFO	1
+#define RTLD_DI_CONFIGADDR	2
+#define RTLD_DI_LMID		4
+#define RTLD_DI_SERINFO		5
+#define RTLD_DI_SERINFOSIZE	6
+#define RTLD_DI_ORIGIN		7
+#define RTLD_DI_GETSIGNAL	8
+#define RTLD_DI_SETSIGNAL	9
+#endif
+#endif /* _NETBSD_SOURCE */
+
+#endif /* !defined(_DLFCN_H_) */
diff --git a/cpukit/libdl/fastlz.c b/cpukit/libdl/fastlz.c
new file mode 100644
index 0000000..3c9d6f6
--- /dev/null
+++ b/cpukit/libdl/fastlz.c
@@ -0,0 +1,551 @@
+/*  
+  FastLZ - lightning-fast lossless compression library
+
+  Copyright (C) 2007 Ariya Hidayat (ariya at kde.org)
+  Copyright (C) 2006 Ariya Hidayat (ariya at kde.org)
+  Copyright (C) 2005 Ariya Hidayat (ariya at kde.org)
+
+  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.
+*/
+
+#if !defined(FASTLZ__COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR)
+
+/*
+ * Always check for bound when decompressing.
+ * Generally it is best to leave it defined.
+ */
+#define FASTLZ_SAFE
+
+/*
+ * Give hints to the compiler for branch prediction optimization.
+ */
+#if defined(__GNUC__) && (__GNUC__ > 2)
+#define FASTLZ_EXPECT_CONDITIONAL(c)    (__builtin_expect((c), 1))
+#define FASTLZ_UNEXPECT_CONDITIONAL(c)  (__builtin_expect((c), 0))
+#else
+#define FASTLZ_EXPECT_CONDITIONAL(c)    (c)
+#define FASTLZ_UNEXPECT_CONDITIONAL(c)  (c)
+#endif
+
+/*
+ * Use inlined functions for supported systems.
+ */
+#if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C)
+#define FASTLZ_INLINE inline
+#elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__)
+#define FASTLZ_INLINE __inline
+#else 
+#define FASTLZ_INLINE
+#endif
+
+/*
+ * Prevent accessing more than 8-bit at once, except on x86 architectures.
+ */
+#if !defined(FASTLZ_STRICT_ALIGN)
+#define FASTLZ_STRICT_ALIGN
+#if defined(__i386__) || defined(__386)  /* GNU C, Sun Studio */
+#undef FASTLZ_STRICT_ALIGN
+#elif defined(__i486__) || defined(__i586__) || defined(__i686__) /* GNU C */
+#undef FASTLZ_STRICT_ALIGN
+#elif defined(_M_IX86) /* Intel, MSVC */
+#undef FASTLZ_STRICT_ALIGN
+#elif defined(__386)
+#undef FASTLZ_STRICT_ALIGN
+#elif defined(_X86_) /* MinGW */
+#undef FASTLZ_STRICT_ALIGN
+#elif defined(__I86__) /* Digital Mars */
+#undef FASTLZ_STRICT_ALIGN
+#endif
+#endif
+
+/*
+ * FIXME: use preprocessor magic to set this on different platforms!
+ */
+typedef unsigned char  flzuint8;
+typedef unsigned short flzuint16;
+typedef unsigned int   flzuint32;
+
+/* prototypes */
+int fastlz_compress(const void* input, int length, void* output);
+int fastlz_compress_level(int level, const void* input, int length, void* output);
+int fastlz_decompress(const void* input, int length, void* output, int maxout);
+
+#define MAX_COPY       32
+#define MAX_LEN       264  /* 256 + 8 */
+#define MAX_DISTANCE 8192
+
+#if !defined(FASTLZ_STRICT_ALIGN)
+#define FASTLZ_READU16(p) *((const flzuint16*)(p)) 
+#else
+#define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8)
+#endif
+
+#define HASH_LOG  13
+#define HASH_SIZE (1<< HASH_LOG)
+#define HASH_MASK  (HASH_SIZE-1)
+#define HASH_FUNCTION(v,p) { v = FASTLZ_READU16(p); v ^= FASTLZ_READU16(p+1)^(v>>(16-HASH_LOG));v &= HASH_MASK; }
+
+#undef FASTLZ_LEVEL
+#define FASTLZ_LEVEL 1
+
+#undef FASTLZ_COMPRESSOR
+#undef FASTLZ_DECOMPRESSOR
+#define FASTLZ_COMPRESSOR fastlz1_compress
+#define FASTLZ_DECOMPRESSOR fastlz1_decompress
+static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
+static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
+#include "fastlz.c"
+
+#undef FASTLZ_LEVEL
+#define FASTLZ_LEVEL 2
+
+#undef MAX_DISTANCE
+#define MAX_DISTANCE 8191
+#define MAX_FARDISTANCE (65535+MAX_DISTANCE-1)
+
+#undef FASTLZ_COMPRESSOR
+#undef FASTLZ_DECOMPRESSOR
+#define FASTLZ_COMPRESSOR fastlz2_compress
+#define FASTLZ_DECOMPRESSOR fastlz2_decompress
+static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
+static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
+#include "fastlz.c"
+
+int fastlz_compress(const void* input, int length, void* output)
+{
+  /* for short block, choose fastlz1 */
+  if(length < 65536)
+    return fastlz1_compress(input, length, output);
+
+  /* else... */
+  return fastlz2_compress(input, length, output);
+}
+
+int fastlz_decompress(const void* input, int length, void* output, int maxout)
+{
+  /* magic identifier for compression level */
+  int level = ((*(const flzuint8*)input) >> 5) + 1;
+
+  if(level == 1)
+    return fastlz1_decompress(input, length, output, maxout);
+  if(level == 2)
+    return fastlz2_decompress(input, length, output, maxout);
+
+  /* unknown level, trigger error */
+  return 0;
+}
+
+int fastlz_compress_level(int level, const void* input, int length, void* output)
+{
+  if(level == 1)
+    return fastlz1_compress(input, length, output);
+  if(level == 2)
+    return fastlz2_compress(input, length, output);
+
+  return 0;
+}
+
+#else /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
+
+static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output)
+{
+  const flzuint8* ip = (const flzuint8*) input;
+  const flzuint8* ip_bound = ip + length - 2;
+  const flzuint8* ip_limit = ip + length - 12;
+  flzuint8* op = (flzuint8*) output;
+
+  const flzuint8* htab[HASH_SIZE];
+  const flzuint8** hslot;
+  flzuint32 hval;
+
+  flzuint32 copy;
+
+  /* sanity check */
+  if(FASTLZ_UNEXPECT_CONDITIONAL(length < 4))
+  {
+    if(length)
+    {
+      /* create literal copy only */
+      *op++ = length-1;
+      ip_bound++;
+      while(ip <= ip_bound)
+        *op++ = *ip++;
+      return length+1;
+    }
+    else
+      return 0;
+  }
+
+  /* initializes hash table */
+  for (hslot = htab; hslot < htab + HASH_SIZE; hslot++)
+    *hslot = ip;
+
+  /* we start with literal copy */
+  copy = 2;
+  *op++ = MAX_COPY-1;
+  *op++ = *ip++;
+  *op++ = *ip++;
+
+  /* main loop */
+  while(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
+  {
+    const flzuint8* ref;
+    flzuint32 distance;
+
+    /* minimum match length */
+    flzuint32 len = 3;
+
+    /* comparison starting-point */
+    const flzuint8* anchor = ip;
+
+    /* check for a run */
+#if FASTLZ_LEVEL==2
+    if(ip[0] == ip[-1] && FASTLZ_READU16(ip-1)==FASTLZ_READU16(ip+1))
+    {
+      distance = 1;
+      ip += 3;
+      ref = anchor - 1 + 3;
+      goto match;
+    }
+#endif
+
+    /* find potential match */
+    HASH_FUNCTION(hval,ip);
+    hslot = htab + hval;
+    ref = htab[hval];
+
+    /* calculate distance to the match */
+    distance = anchor - ref;
+
+    /* update hash table */
+    *hslot = anchor;
+
+    /* is this a match? check the first 3 bytes */
+    if(distance==0 || 
+#if FASTLZ_LEVEL==1
+    (distance >= MAX_DISTANCE) ||
+#else
+    (distance >= MAX_FARDISTANCE) ||
+#endif
+    *ref++ != *ip++ || *ref++!=*ip++ || *ref++!=*ip++)
+      goto literal;
+
+#if FASTLZ_LEVEL==2
+    /* far, needs at least 5-byte match */
+    if(distance >= MAX_DISTANCE)
+    {
+      if(*ip++ != *ref++ || *ip++!= *ref++) 
+        goto literal;
+      len += 2;
+    }
+    
+    match:
+#endif
+
+    /* last matched byte */
+    ip = anchor + len;
+
+    /* distance is biased */
+    distance--;
+
+    if(!distance)
+    {
+      /* zero distance means a run */
+      flzuint8 x = ip[-1];
+      while(ip < ip_bound)
+        if(*ref++ != x) break; else ip++;
+    }
+    else
+    for(;;)
+    {
+      /* safe because the outer check against ip limit */
+      if(*ref++ != *ip++) break;
+      if(*ref++ != *ip++) break;
+      if(*ref++ != *ip++) break;
+      if(*ref++ != *ip++) break;
+      if(*ref++ != *ip++) break;
+      if(*ref++ != *ip++) break;
+      if(*ref++ != *ip++) break;
+      if(*ref++ != *ip++) break;
+      while(ip < ip_bound)
+        if(*ref++ != *ip++) break;
+      break;
+    }
+
+    /* if we have copied something, adjust the copy count */
+    if(copy)
+      /* copy is biased, '0' means 1 byte copy */
+      *(op-copy-1) = copy-1;
+    else
+      /* back, to overwrite the copy count */
+      op--;
+
+    /* reset literal counter */
+    copy = 0;
+
+    /* length is biased, '1' means a match of 3 bytes */
+    ip -= 3;
+    len = ip - anchor;
+
+    /* encode the match */
+#if FASTLZ_LEVEL==2
+    if(distance < MAX_DISTANCE)
+    {
+      if(len < 7)
+      {
+        *op++ = (len << 5) + (distance >> 8);
+        *op++ = (distance & 255);
+      }
+      else
+      {
+        *op++ = (7 << 5) + (distance >> 8);
+        for(len-=7; len >= 255; len-= 255)
+          *op++ = 255;
+        *op++ = len;
+        *op++ = (distance & 255);
+      }
+    }
+    else
+    {
+      /* far away, but not yet in the another galaxy... */
+      if(len < 7)
+      {
+        distance -= MAX_DISTANCE;
+        *op++ = (len << 5) + 31;
+        *op++ = 255;
+        *op++ = distance >> 8;
+        *op++ = distance & 255;
+      }
+      else
+      {
+        distance -= MAX_DISTANCE;
+        *op++ = (7 << 5) + 31;
+        for(len-=7; len >= 255; len-= 255)
+          *op++ = 255;
+        *op++ = len;
+        *op++ = 255;
+        *op++ = distance >> 8;
+        *op++ = distance & 255;
+      }
+    }
+#else
+
+    if(FASTLZ_UNEXPECT_CONDITIONAL(len > MAX_LEN-2))
+      while(len > MAX_LEN-2)
+      {
+        *op++ = (7 << 5) + (distance >> 8);
+        *op++ = MAX_LEN - 2 - 7 -2; 
+        *op++ = (distance & 255);
+        len -= MAX_LEN-2;
+      }
+
+    if(len < 7)
+    {
+      *op++ = (len << 5) + (distance >> 8);
+      *op++ = (distance & 255);
+    }
+    else
+    {
+      *op++ = (7 << 5) + (distance >> 8);
+      *op++ = len - 7;
+      *op++ = (distance & 255);
+    }
+#endif
+
+    /* update the hash at match boundary */
+    HASH_FUNCTION(hval,ip);
+    htab[hval] = ip++;
+    HASH_FUNCTION(hval,ip);
+    htab[hval] = ip++;
+
+    /* assuming literal copy */
+    *op++ = MAX_COPY-1;
+
+    continue;
+
+    literal:
+      *op++ = *anchor++;
+      ip = anchor;
+      copy++;
+      if(FASTLZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY))
+      {
+        copy = 0;
+        *op++ = MAX_COPY-1;
+      }
+  }
+
+  /* left-over as literal copy */
+  ip_bound++;
+  while(ip <= ip_bound)
+  {
+    *op++ = *ip++;
+    copy++;
+    if(copy == MAX_COPY)
+    {
+      copy = 0;
+      *op++ = MAX_COPY-1;
+    }
+  }
+
+  /* if we have copied something, adjust the copy length */
+  if(copy)
+    *(op-copy-1) = copy-1;
+  else
+    op--;
+
+#if FASTLZ_LEVEL==2
+  /* marker for fastlz2 */
+  *(flzuint8*)output |= (1 << 5);
+#endif
+
+  return op - (flzuint8*)output;
+}
+
+static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout)
+{
+  const flzuint8* ip = (const flzuint8*) input;
+  const flzuint8* ip_limit  = ip + length;
+  flzuint8* op = (flzuint8*) output;
+  flzuint8* op_limit = op + maxout;
+  flzuint32 ctrl = (*ip++) & 31;
+  int loop = 1;
+
+  do
+  {
+    const flzuint8* ref = op;
+    flzuint32 len = ctrl >> 5;
+    flzuint32 ofs = (ctrl & 31) << 8;
+
+    if(ctrl >= 32)
+    {
+#if FASTLZ_LEVEL==2
+      flzuint8 code;
+#endif
+      len--;
+      ref -= ofs;
+      if (len == 7-1)
+#if FASTLZ_LEVEL==1
+        len += *ip++;
+      ref -= *ip++;
+#else
+        do
+        {
+          code = *ip++;
+          len += code;
+        } while (code==255);
+      code = *ip++;
+      ref -= code;
+
+      /* match from 16-bit distance */
+      if(FASTLZ_UNEXPECT_CONDITIONAL(code==255))
+      if(FASTLZ_EXPECT_CONDITIONAL(ofs==(31 << 8)))
+      {
+        ofs = (*ip++) << 8;
+        ofs += *ip++;
+        ref = op - ofs - MAX_DISTANCE;
+      }
+#endif
+      
+#ifdef FASTLZ_SAFE
+      if (FASTLZ_UNEXPECT_CONDITIONAL(op + len + 3 > op_limit))
+        return 0;
+
+      if (FASTLZ_UNEXPECT_CONDITIONAL(ref-1 < (flzuint8 *)output))
+        return 0;
+#endif
+
+      if(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
+        ctrl = *ip++;
+      else
+        loop = 0;
+
+      if(ref == op)
+      {
+        /* optimize copy for a run */
+        flzuint8 b = ref[-1];
+        *op++ = b;
+        *op++ = b;
+        *op++ = b;
+        for(; len; --len)
+          *op++ = b;
+      }
+      else
+      {
+#if !defined(FASTLZ_STRICT_ALIGN)
+        const flzuint16* p;
+        flzuint16* q;
+#endif
+        /* copy from reference */
+        ref--;
+        *op++ = *ref++;
+        *op++ = *ref++;
+        *op++ = *ref++;
+
+#if !defined(FASTLZ_STRICT_ALIGN)
+        /* copy a byte, so that now it's word aligned */
+        if(len & 1)
+        {
+          *op++ = *ref++;
+          len--;
+        }
+
+        /* copy 16-bit at once */
+        q = (flzuint16*) op;
+        op += len;
+        p = (const flzuint16*) ref;
+        for(len>>=1; len > 4; len-=4)
+        {
+          *q++ = *p++;
+          *q++ = *p++;
+          *q++ = *p++;
+          *q++ = *p++;
+        }
+        for(; len; --len)
+          *q++ = *p++;
+#else
+        for(; len; --len)
+          *op++ = *ref++;
+#endif
+      }
+    }
+    else
+    {
+      ctrl++;
+#ifdef FASTLZ_SAFE
+      if (FASTLZ_UNEXPECT_CONDITIONAL(op + ctrl > op_limit))
+        return 0;
+      if (FASTLZ_UNEXPECT_CONDITIONAL(ip + ctrl > ip_limit))
+        return 0;
+#endif
+
+      *op++ = *ip++; 
+      for(--ctrl; ctrl; ctrl--)
+        *op++ = *ip++;
+
+      loop = FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit);
+      if(loop)
+        ctrl = *ip++;
+    }
+  }
+  while(FASTLZ_EXPECT_CONDITIONAL(loop));
+
+  return op - (flzuint8*)output;
+}
+
+#endif /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
diff --git a/cpukit/libdl/fastlz.h b/cpukit/libdl/fastlz.h
new file mode 100644
index 0000000..f87bc7b
--- /dev/null
+++ b/cpukit/libdl/fastlz.h
@@ -0,0 +1,100 @@
+/*  
+  FastLZ - lightning-fast lossless compression library
+
+  Copyright (C) 2007 Ariya Hidayat (ariya at kde.org)
+  Copyright (C) 2006 Ariya Hidayat (ariya at kde.org)
+  Copyright (C) 2005 Ariya Hidayat (ariya at kde.org)
+
+  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 FASTLZ_H
+#define FASTLZ_H
+
+#define FASTLZ_VERSION 0x000100
+
+#define FASTLZ_VERSION_MAJOR     0
+#define FASTLZ_VERSION_MINOR     0
+#define FASTLZ_VERSION_REVISION  0
+
+#define FASTLZ_VERSION_STRING "0.1.0"
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/**
+  Compress a block of data in the input buffer and returns the size of 
+  compressed block. The size of input buffer is specified by length. The 
+  minimum input buffer size is 16.
+
+  The output buffer must be at least 5% larger than the input buffer  
+  and can not be smaller than 66 bytes.
+
+  If the input is not compressible, the return value might be larger than
+  length (input buffer size).
+
+  The input buffer and the output buffer can not overlap.
+*/
+
+int fastlz_compress(const void* input, int length, void* output);
+
+/**
+  Decompress a block of compressed data and returns the size of the 
+  decompressed block. If error occurs, e.g. the compressed data is 
+  corrupted or the output buffer is not large enough, then 0 (zero) 
+  will be returned instead.
+
+  The input buffer and the output buffer can not overlap.
+
+  Decompression is memory safe and guaranteed not to write the output buffer
+  more than what is specified in maxout.
+ */
+
+int fastlz_decompress(const void* input, int length, void* output, int maxout); 
+
+/**
+  Compress a block of data in the input buffer and returns the size of 
+  compressed block. The size of input buffer is specified by length. The 
+  minimum input buffer size is 16.
+
+  The output buffer must be at least 5% larger than the input buffer  
+  and can not be smaller than 66 bytes.
+
+  If the input is not compressible, the return value might be larger than
+  length (input buffer size).
+
+  The input buffer and the output buffer can not overlap.
+
+  Compression level can be specified in parameter level. At the moment, 
+  only level 1 and level 2 are supported.
+  Level 1 is the fastest compression and generally useful for short data.
+  Level 2 is slightly slower but it gives better compression ratio.
+
+  Note that the compressed data, regardless of the level, can always be
+  decompressed using the function fastlz_decompress above.
+*/  
+
+int fastlz_compress_level(int level, const void* input, int length, void* output);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* FASTLZ_H */
diff --git a/cpukit/libdl/include/arch/arm/machine/elf_machdep.h b/cpukit/libdl/include/arch/arm/machine/elf_machdep.h
new file mode 100644
index 0000000..78c88b5
--- /dev/null
+++ b/cpukit/libdl/include/arch/arm/machine/elf_machdep.h
@@ -0,0 +1,131 @@
+/*	$NetBSD: elf_machdep.h,v 1.8 2009/05/30 05:56:52 skrll Exp $	*/
+
+#if defined(__ARMEB__)
+#define ELF32_MACHDEP_ENDIANNESS	ELFDATA2MSB
+#else
+#define ELF32_MACHDEP_ENDIANNESS	ELFDATA2LSB
+#endif
+
+#define ELF64_MACHDEP_ENDIANNESS	XXX	/* break compilation */
+#define ELF64_MACHDEP_ID_CASES                                          \
+		/* no 64-bit ELF machine types supported */
+
+/* Processor specific flags for the ELF header e_flags field.  */
+#define EF_ARM_RELEXEC		0x00000001
+#define EF_ARM_HASENTRY		0x00000002
+#define EF_ARM_INTERWORK	0x00000004 /* GNU binutils 000413 */
+#define EF_ARM_SYMSARESORTED	0x00000004 /* ARM ELF A08 */
+#define EF_ARM_APCS_26		0x00000008 /* GNU binutils 000413 */
+#define EF_ARM_DYNSYMSUSESEGIDX	0x00000008 /* ARM ELF B01 */
+#define EF_ARM_APCS_FLOAT	0x00000010 /* GNU binutils 000413 */
+#define EF_ARM_MAPSYMSFIRST	0x00000010 /* ARM ELF B01 */
+#define EF_ARM_PIC		0x00000020
+#define EF_ARM_ALIGN8		0x00000040 /* 8-bit structure alignment.  */
+#define EF_ARM_NEW_ABI		0x00000080
+#define EF_ARM_OLD_ABI		0x00000100
+#define EF_ARM_SOFT_FLOAT	0x00000200
+#define EF_ARM_EABIMASK		0xff000000
+
+#define	ELF32_MACHDEP_ID_CASES						\
+		case EM_ARM:						\
+			break;
+
+#define	ELF32_MACHDEP_ID	EM_ARM
+
+#define ARCH_ELFSIZE		32	/* MD native binary size */
+
+/* Processor specific relocation types */
+
+#define R_ARM_NONE		0
+#define R_ARM_PC24		1
+#define R_ARM_ABS32		2
+#define R_ARM_REL32		3
+#define R_ARM_PC13		4
+#define R_ARM_ABS16		5
+#define R_ARM_ABS12		6
+#define R_ARM_THM_ABS5		7
+#define R_ARM_ABS8		8
+#define R_ARM_SBREL32		9
+#define R_ARM_THM_CALL  10
+#define R_ARM_THM_PC8		11
+#define R_ARM_AMP_VCALL9	12
+#define R_ARM_SWI24		13
+#define R_ARM_THM_SWI8		14
+#define R_ARM_XPC25		15
+#define R_ARM_THM_XPC22		16
+
+/* TLS relocations */
+#define R_ARM_TLS_DTPMOD32	17	/* ID of module containing symbol */
+#define R_ARM_TLS_DTPOFF32	18	/* Offset in TLS block */
+#define R_ARM_TLS_TPOFF32	19	/* Offset in static TLS block */
+
+/* 20-31 are reserved for ARM Linux. */
+#define R_ARM_COPY		20
+#define R_ARM_GLOB_DAT		21
+#define	R_ARM_JUMP_SLOT		22
+#define R_ARM_RELATIVE		23
+#define	R_ARM_GOTOFF		24
+#define R_ARM_GOTPC		25
+#define R_ARM_GOT32		26
+#define R_ARM_PLT32		27
+#define R_ARM_CALL        28
+#define R_ARM_JUMP24      29
+#define R_ARM_THM_JUMP24	30
+#define R_ARM_BASE_ABS  	31
+
+#define R_ARM_ALU_PCREL_7_0	32
+#define R_ARM_ALU_PCREL_15_8	33
+#define R_ARM_ALU_PCREL_23_15	34
+#define R_ARM_ALU_SBREL_11_0	35
+#define R_ARM_ALU_SBREL_19_12	36
+#define R_ARM_ALU_SBREL_27_20	37
+#define R_ARM_V4BX        40
+#define R_ARM_PREL31      41
+
+#define R_ARM_MOVW_ABS_NC     43
+#define R_ARM_MOVT_ABS        44
+
+#define R_ARM_THM_MOVW_ABS_NC 47
+#define R_ARM_THM_MOVT_ABS    48
+
+#define R_ARM_THM_JUMP19      51
+
+/* 96-111 are reserved to G++. */
+#define R_ARM_GNU_VTENTRY	100
+#define R_ARM_GNU_VTINHERIT	101
+#define R_ARM_THM_JUMP11		102
+#define R_ARM_THM_JUMP8		103
+
+/* More TLS relocations */
+#define R_ARM_TLS_GD32		104	/* PC-rel 32 bit for global dynamic */
+#define R_ARM_TLS_LDM32		105	/* PC-rel 32 bit for local dynamic */
+#define R_ARM_TLS_LDO32		106	/* 32 bit offset relative to TLS */
+#define R_ARM_TLS_IE32		107	/* PC-rel 32 bit for GOT entry of */
+#define R_ARM_TLS_LE32		108
+#define R_ARM_TLS_LDO12		109
+#define R_ARM_TLS_LE12		110
+#define R_ARM_TLS_IE12GP	111
+
+/* 112-127 are reserved for private experiments. */
+
+#define R_ARM_RXPC25		249
+#define R_ARM_RSBREL32		250
+#define R_ARM_THM_RPC22		251
+#define R_ARM_RREL32		252
+#define R_ARM_RABS32		253
+#define R_ARM_RPC24		254
+#define R_ARM_RBASE		255
+
+#define R_TYPE(name)		__CONCAT(R_ARM_,name)
+
+/* Processor specific program header flags */
+#define PF_ARM_SB		0x10000000
+#define PF_ARM_PI		0x20000000
+#define PF_ARM_ENTRY		0x80000000
+
+/* Processor specific section header flags */
+#define SHF_ENTRYSECT		0x10000000
+#define SHF_COMDEF		0x80000000
+
+/* Processor specific symbol types */
+#define STT_ARM_TFUNC		STT_LOPROC
diff --git a/cpukit/libdl/include/arch/bfin/machine/elf_machdep.h b/cpukit/libdl/include/arch/bfin/machine/elf_machdep.h
new file mode 100644
index 0000000..cf0dc19
--- /dev/null
+++ b/cpukit/libdl/include/arch/bfin/machine/elf_machdep.h
@@ -0,0 +1,28 @@
+#define ELF32_MACHDEP_ENDIANNESS  ELFDATA2LSB
+
+#define ELF32_MACHDEP_ID_CASES \
+  case EM_BLACKFIN: \
+    break;
+
+#define ELF32_MACHDEP_ID  EM_BLACKFIN
+
+#define ARCH_ELFSIZE          32
+
+#define R_BFIN_UNUSED0        0
+
+#define R_BFIN_RIMM16         5
+#define R_BFIN_LUIMM16        6
+#define R_BFIN_HUIMM16        7
+#define R_BFIN_PCREL12_JUMP_S 8
+#define R_BFIN_PCREL24_JUMP_X 9
+#define R_BFIN_PCREL24        10
+#define R_BFIN_PCREL24_JU     13
+#define R_BFIN_PCREL24_CALL_X 14
+
+#define R_BFIN_BYTE_DATA      16
+#define R_BFIN_BYTE2_DATA     17
+#define R_BFIN_BYTE4_DATA     18
+
+
+
+#define R_TYPE(name)    __CONCAT(R_BFIN_,name)
diff --git a/cpukit/libdl/include/arch/h8300/machine/elf_machdep.h b/cpukit/libdl/include/arch/h8300/machine/elf_machdep.h
new file mode 100644
index 0000000..3d04915
--- /dev/null
+++ b/cpukit/libdl/include/arch/h8300/machine/elf_machdep.h
@@ -0,0 +1,59 @@
+
+#define ELF32_MACHDEP_ENDIANNESS		ELFDATA2MSB
+
+#define ELF32_MACHDEP_ID_CASES \
+	case EM_H8_300: \
+	case EM_H8_300H: \
+	case EM_H8S: \
+	case EM_H8_500: \
+		break;
+
+#define ELF32_MACHDEP_ID	EM_H8_300
+#define ARCH_ELFSIZE	32
+
+#define R_H8_NONE 0
+#define R_H8_DIR32 1
+#define R_H8_DIR32_28 2
+#define R_H8_DIR32_24 3
+#define R_H8_DIR32_16 4
+#define R_H8_DIR32U 6
+#define R_H8_DIR32U_28 7
+#define R_H8_DIR32U_24 8
+#define R_H8_DIR32U_20 9
+#define R_H8_DIR32U_16 10
+#define R_H8_DIR24 11
+#define R_H8_DIR24_20 12
+#define R_H8_DIR24_16 13
+#define R_H8_DIR24U 14
+#define R_H8_DIR24U_20 15
+#define R_H8_DIR24U_16 16
+#define R_H8_DIR16 17
+#define R_H8_DIR16U 18
+#define R_H8_DIR16S_32 19
+#define R_H8_DIR16S_28 20
+#define R_H8_DIR16S_24 21
+#define R_H8_DIR16S_20 22
+#define R_H8_DIR16S 23
+#define R_H8_DIR8 24
+#define R_H8_DIR8U 25
+#define R_H8_DIR8Z_32 26
+#define R_H8_DIR8Z_28 27
+#define R_H8_DIR8Z_24 28
+#define R_H8_DIR8Z_20 29
+#define R_H8_DIR8Z_16 30
+#define R_H8_PCREL16 31
+#define R_H8_PCREL8 32
+#define R_H8_BPOS 33
+#define R_H8_PCREL32 34
+#define R_H8_GOT32O 35
+#define R_H8_GOT16O 36
+#define R_H8_DIR16A8 59
+#define R_H8_DIR16R8 60
+#define R_H8_DIR24A8 61
+#define R_H8_DIR24R8 62
+#define R_H8_DIR32A16 63
+#define R_H8_ABS32 65
+#define R_H8_ABS32A16 127
+
+
+#define R_TYPE(name)		__CONCAT(R_H8_,name)
diff --git a/cpukit/libdl/include/arch/i386/machine/elf_machdep.h b/cpukit/libdl/include/arch/i386/machine/elf_machdep.h
new file mode 100644
index 0000000..442c561
--- /dev/null
+++ b/cpukit/libdl/include/arch/i386/machine/elf_machdep.h
@@ -0,0 +1,63 @@
+/*	$NetBSD: elf_machdep.h,v 1.10 2009/05/30 05:56:52 skrll Exp $	*/
+
+#define	ELF32_MACHDEP_ENDIANNESS	ELFDATA2LSB
+#define	ELF32_MACHDEP_ID_CASES						\
+		case EM_386:						\
+		case EM_486:						\
+			break;
+
+#define	ELF64_MACHDEP_ENDIANNESS	XXX	/* break compilation */
+#define	ELF64_MACHDEP_ID_CASES						\
+		/* no 64-bit ELF machine types supported */
+
+#define	ELF32_MACHDEP_ID		EM_386
+
+#define ARCH_ELFSIZE		32	/* MD native binary size */
+
+/* i386 relocations */
+#define	R_386_NONE	0
+#define	R_386_32	1
+#define	R_386_PC32	2
+#define	R_386_GOT32	3
+#define	R_386_PLT32	4
+#define	R_386_COPY	5
+#define	R_386_GLOB_DAT	6
+#define	R_386_JMP_SLOT	7
+#define	R_386_RELATIVE	8
+#define	R_386_GOTOFF	9
+#define	R_386_GOTPC	10
+
+/* TLS relocations */
+#define	R_386_TLS_TPOFF	14
+#define	R_386_TLS_IE	15
+#define	R_386_TLS_GOTIE	16
+#define	R_386_TLS_LE	17
+#define	R_386_TLS_GD	18
+#define	R_386_TLS_LDM	19
+
+/* The following relocations are GNU extensions. */
+#define	R_386_16	20
+#define	R_386_PC16	21
+#define	R_386_8		22
+#define	R_386_PC8	23
+
+/* More TLS relocations */
+#define	R_386_TLS_GD_32		24
+#define	R_386_TLS_GD_PUSH	25
+#define	R_386_TLS_GD_CALL	26
+#define	R_386_TLS_GD_POP	27
+#define	R_386_TLS_LDM_32	28
+#define	R_386_TLS_LDM_PUSH	29
+#define	R_386_TLS_LDM_CALL	30
+#define	R_386_TLS_LDM_POP	31
+#define	R_386_TLS_LDO_32	32
+#define	R_386_TLS_IE_32		33
+#define	R_386_TLS_LE_32		34
+#define	R_386_TLS_DTPMOD32	35
+#define	R_386_TLS_DTPOFF32	36
+#define	R_386_TLS_TPOFF32	37
+#define	R_386_TLS_GOTDESC	39
+#define	R_386_TLS_DESC_CALL	40
+#define	R_386_TLS_DESC		41
+
+#define	R_TYPE(name)	__CONCAT(R_386_,name)
diff --git a/cpukit/libdl/include/arch/lm32/machine/elf_machdep.h b/cpukit/libdl/include/arch/lm32/machine/elf_machdep.h
new file mode 100644
index 0000000..29c75b8
--- /dev/null
+++ b/cpukit/libdl/include/arch/lm32/machine/elf_machdep.h
@@ -0,0 +1,34 @@
+#define ELF32_MACHDEP_ENDIANNESS		ELFDATA2MSB
+
+#define ELF32_MACHDEP_ID_CASES \
+	case EM_LATTICEMICO32: \
+		break;
+
+#define ELF32_MACHDEP_ID	EM_LATTICEMICO32
+
+#define EF_MACH32_MACH		0x00000001
+
+//#define EF_BLACKFIN
+
+#define ARCH_ELFSIZE	32
+
+#define R_LM32_NONE			0
+#define R_LM32_8				1
+#define R_LM32_16				2
+#define R_LM32_32				3
+#define R_LM32_HI16			4
+#define R_LM32_LO16			5
+#define R_LM32_GPREL16	6
+#define R_LM32_CALL			7
+#define R_LM32_BRANCH		8
+#define	R_LM32_GNU_VTINHERIT	9
+#define R_LM32_GNU_VTENTRY		10
+#define R_LM32_16_GOT		11
+#define R_LM32_GOTOFF_HI16		12
+#define	R_LM32_GOTOFF_LO16		13
+#define R_LM32_COPY			14
+#define R_LM32_GLOT_DAT	15
+#define R_LM32_JMP_SLOT	16
+#define R_LM32_RELATIVE	17
+
+#define R_TYPE(name)		__CONCAT(R_LM32_,name)
diff --git a/cpukit/libdl/include/arch/m32r/machine/elf_machdep.h b/cpukit/libdl/include/arch/m32r/machine/elf_machdep.h
new file mode 100644
index 0000000..3f531cf
--- /dev/null
+++ b/cpukit/libdl/include/arch/m32r/machine/elf_machdep.h
@@ -0,0 +1,39 @@
+#define ELF32_MACHDEP_ENDIANNESS		ELFDATA2MSB
+
+#define ELF32_MACHDEP_ID_CASES \
+	case EM_M32R: \
+		break;
+
+#define ELF32_MACHDEP_ID	EM_M32R
+
+#define ARCH_ELFSIZE	32
+
+#define R_M32R_NONE 0
+/*-----------OLD TYPE-------------*/
+#define R_M32R_16            1
+#define R_M32R_32            2
+#define R_M32R_24            3
+#define R_M32R_10_PCREL      4
+#define R_M32R_18_PCREL      5
+#define R_M32R_26_PCREL      6
+#define R_M32R_HI16_ULO      7
+#define R_M32R_HI16_SLO      8
+#define R_M32R_LO16          9
+#define R_M32R_SDA16         10
+#define R_M32R_GNU_VTINHERIT 11
+#define R_M32R_GNU_VTENTRY   12
+/*--------------------------------*/
+
+#define R_M32R_16_RELA       33
+#define R_M32R_32_RELA       34
+#define R_M32R_24_RELA       35
+#define R_M32R_18_PCREL_RELA 37
+#define R_M32R_26_PCREL_RELA 38
+#define R_M32R_HI16_ULO_RELA 39
+#define R_M32R_HI16_SLO_RELA 40
+#define R_M32R_LO16_RELA     41
+#define R_M32R_SDA16_RELA    42
+#define R_M32R_RELA_GNU_VTINHERIT 43
+#define R_M32R_RELA_GNU_VTENTRY   44
+
+#define R_TYPE(name)		__CONCAT(R_M32R_,name)
diff --git a/cpukit/libdl/include/arch/m68k/machine/elf_machdep.h b/cpukit/libdl/include/arch/m68k/machine/elf_machdep.h
new file mode 100644
index 0000000..9a987c6
--- /dev/null
+++ b/cpukit/libdl/include/arch/m68k/machine/elf_machdep.h
@@ -0,0 +1,47 @@
+/*	$NetBSD: elf_machdep.h,v 1.7 2002/01/28 21:34:48 thorpej Exp $	*/
+
+#define	ELF32_MACHDEP_ENDIANNESS	ELFDATA2MSB
+#define	ELF32_MACHDEP_ID_CASES						\
+		case EM_68K:						\
+			break;
+
+#define	ELF64_MACHDEP_ENDIANNESS	XXX	/* break compilation */
+#define	ELF64_MACHDEP_ID_CASES						\
+		/* no 64-bit ELF machine types supported */
+
+#define	ELF32_MACHDEP_ID	EM_68K
+
+/*
+ * Machine-dependent ELF flags.  These are defined by the GNU tools.
+ */
+#define	EF_CPU32	0x00810000
+#define	EF_M68000	0x01000000
+
+#define ARCH_ELFSIZE		32	/* MD native binary size */
+
+/* m68k relocation types */
+#define	R_68K_NONE	0
+#define	R_68K_32	1
+#define	R_68K_16	2
+#define	R_68K_8		3
+#define	R_68K_PC32	4
+#define	R_68K_PC16	5
+#define	R_68K_PC8	6
+#define	R_68K_GOT32	7
+#define	R_68K_GOT16	8
+#define	R_68K_GOT8	9
+#define	R_68K_GOT32O	10
+#define	R_68K_GOT16O	11
+#define	R_68K_GOT8O	12
+#define	R_68K_PLT32	13
+#define	R_68K_PLT16	14
+#define	R_68K_PLT8	15
+#define	R_68K_PLT32O	16
+#define	R_68K_PLT16O	17
+#define	R_68K_PLT8O	18
+#define	R_68K_COPY	19
+#define	R_68K_GLOB_DAT	20
+#define	R_68K_JMP_SLOT	21
+#define	R_68K_RELATIVE	22
+
+#define	R_TYPE(name)	__CONCAT(R_68K_,name)
diff --git a/cpukit/libdl/include/arch/mips/machine/elf_machdep.h b/cpukit/libdl/include/arch/mips/machine/elf_machdep.h
new file mode 100644
index 0000000..d27d431
--- /dev/null
+++ b/cpukit/libdl/include/arch/mips/machine/elf_machdep.h
@@ -0,0 +1,196 @@
+/*	$NetBSD: elf_machdep.h,v 1.15 2011/03/15 07:39:22 matt Exp $	*/
+
+#ifndef _MIPS_ELF_MACHDEP_H_
+#define  _MIPS_ELF_MACHDEP_H_
+
+#ifdef _LP64
+#define ARCH_ELFSIZE		64	/* MD native binary size */
+#else
+#define ARCH_ELFSIZE		32	/* MD native binary size */
+#endif
+
+#if ELFSIZE == 32
+#define	ELF32_MACHDEP_ID_CASES						\
+		case EM_MIPS:						\
+			break;
+
+#define	ELF32_MACHDEP_ID	EM_MIPS
+#elif ELFSIZE == 64
+#define	ELF64_MACHDEP_ID_CASES						\
+		case EM_MIPS:						\
+			break;
+
+#define	ELF64_MACHDEP_ID	EM_MIPS
+#endif
+
+/* mips relocs.  */
+
+#define R_MIPS_NONE		0
+#define R_MIPS_16		1
+#define R_MIPS_32		2
+#define R_MIPS_REL32		3
+#define R_MIPS_REL		R_MIPS_REL32
+#define R_MIPS_26		4
+#define R_MIPS_HI16		5	/* high 16 bits of symbol value */
+#define R_MIPS_LO16		6	/* low 16 bits of symbol value */
+#define R_MIPS_GPREL16		7  	/* GP-relative reference  */
+#define R_MIPS_LITERAL		8 	/* Reference to literal section  */
+#define R_MIPS_GOT16		9	/* Reference to global offset table */
+#define R_MIPS_GOT		R_MIPS_GOT16
+#define R_MIPS_PC16		10  	/* 16 bit PC relative reference */
+#define R_MIPS_CALL16 		11  	/* 16 bit call thru glbl offset tbl */
+#define R_MIPS_CALL		R_MIPS_CALL16
+#define R_MIPS_GPREL32		12
+
+/* 13, 14, 15 are not defined at this point. */
+#define R_MIPS_UNUSED1		13
+#define R_MIPS_UNUSED2		14
+#define R_MIPS_UNUSED3		15
+
+/*
+ * The remaining relocs are apparently part of the 64-bit Irix ELF ABI.
+ */
+#define R_MIPS_SHIFT5		16
+#define R_MIPS_SHIFT6		17
+
+#define R_MIPS_64		18
+#define R_MIPS_GOT_DISP		19
+#define R_MIPS_GOT_PAGE		20
+#define R_MIPS_GOT_OFST		21
+#define R_MIPS_GOT_HI16		22
+#define R_MIPS_GOT_LO16		23
+#define R_MIPS_SUB 		24
+#define R_MIPS_INSERT_A		25
+#define R_MIPS_INSERT_B		26
+#define R_MIPS_DELETE		27
+#define R_MIPS_HIGHER		28
+#define R_MIPS_HIGHEST		29
+#define R_MIPS_CALL_HI16	30
+#define R_MIPS_CALL_LO16	31
+#define R_MIPS_SCN_DISP		32
+#define R_MIPS_REL16		33
+#define R_MIPS_ADD_IMMEDIATE	34
+#define R_MIPS_PJUMP		35
+#define R_MIPS_RELGOT		36
+#define	R_MIPS_JALR		37
+/* TLS relocations */
+
+#define R_MIPS_TLS_DTPMOD32	38	/* Module number 32 bit */
+#define R_MIPS_TLS_DTPREL32	39	/* Module-relative offset 32 bit */
+#define R_MIPS_TLS_DTPMOD64	40	/* Module number 64 bit */
+#define R_MIPS_TLS_DTPREL64	41	/* Module-relative offset 64 bit */
+#define R_MIPS_TLS_GD		42	/* 16 bit GOT offset for GD */
+#define R_MIPS_TLS_LDM		43	/* 16 bit GOT offset for LDM */
+#define R_MIPS_TLS_DTPREL_HI16	44	/* Module-relative offset, high 16 bits */
+#define R_MIPS_TLS_DTPREL_LO16	45	/* Module-relative offset, low 16 bits */
+#define R_MIPS_TLS_GOTTPREL	46	/* 16 bit GOT offset for IE */
+#define R_MIPS_TLS_TPREL32	47	/* TP-relative offset, 32 bit */
+#define R_MIPS_TLS_TPREL64	48	/* TP-relative offset, 64 bit */
+#define R_MIPS_TLS_TPREL_HI16	49	/* TP-relative offset, high 16 bits */
+#define R_MIPS_TLS_TPREL_LO16	50	/* TP-relative offset, low 16 bits */
+
+#define R_MIPS_max		51
+
+#define R_TYPE(name)		__CONCAT(R_MIPS_,name)
+
+#define	R_MIPS16_min		100
+#define	R_MIPS16_26		100
+#define	R_MIPS16_GPREL		101
+#define	R_MIPS16_GOT16		102
+#define	R_MIPS16_CALL16		103
+#define	R_MIPS16_HI16		104
+#define	R_MIPS16_LO16		105
+#define	R_MIPS16_max		106
+
+
+/* mips dynamic tags */
+
+#define DT_MIPS_RLD_VERSION	0x70000001
+#define DT_MIPS_TIME_STAMP	0x70000002
+#define DT_MIPS_ICHECKSUM	0x70000003
+#define DT_MIPS_IVERSION	0x70000004
+#define DT_MIPS_FLAGS		0x70000005
+#define DT_MIPS_BASE_ADDRESS	0x70000006
+#define DT_MIPS_CONFLICT	0x70000008
+#define DT_MIPS_LIBLIST		0x70000009
+#define DT_MIPS_CONFLICTNO	0x7000000b
+#define	DT_MIPS_LOCAL_GOTNO	0x7000000a	/* number of local got ents */
+#define DT_MIPS_LIBLISTNO	0x70000010
+#define	DT_MIPS_SYMTABNO	0x70000011	/* number of .dynsym entries */
+#define DT_MIPS_UNREFEXTNO	0x70000012
+#define	DT_MIPS_GOTSYM		0x70000013	/* first dynamic sym in got */
+#define DT_MIPS_HIPAGENO	0x70000014
+#define	DT_MIPS_RLD_MAP		0x70000016	/* address of loader map */
+
+/*
+ * ELF Flags
+ */
+#define	EF_MIPS_PIC		0x00000002	/* Contains PIC code */
+#define	EF_MIPS_CPIC		0x00000004	/* STD PIC calling sequence */
+#define	EF_MIPS_ABI2		0x00000020	/* N32 */
+
+#define	EF_MIPS_ARCH_ASE	0x0f000000	/* Architectural extensions */
+#define	EF_MIPS_ARCH_MDMX	0x08000000	/* MDMX multimedia extension */
+#define	EF_MIPS_ARCH_M16	0x04000000	/* MIPS-16 ISA extensions */
+
+#define	EF_MIPS_ARCH		0xf0000000	/* Architecture field */
+#define	EF_MIPS_ARCH_1		0x00000000	/* -mips1 code */
+#define	EF_MIPS_ARCH_2		0x10000000	/* -mips2 code */
+#define	EF_MIPS_ARCH_3		0x20000000	/* -mips3 code */
+#define	EF_MIPS_ARCH_4		0x30000000	/* -mips4 code */
+#define	EF_MIPS_ARCH_5		0x40000000	/* -mips5 code */
+#define	EF_MIPS_ARCH_32		0x50000000	/* -mips32 code */
+#define	EF_MIPS_ARCH_64		0x60000000	/* -mips64 code */
+#define	EF_MIPS_ARCH_32R2	0x70000000	/* -mips32r2 code */
+#define	EF_MIPS_ARCH_64R2	0x80000000	/* -mips64r2 code */
+
+#define	EF_MIPS_ABI		0x0000f000
+#define	EF_MIPS_ABI_O32		0x00001000
+#define	EF_MIPS_ABI_O64		0x00002000
+#define	EF_MIPS_ABI_EABI32	0x00003000
+#define	EF_MIPS_ABI_EABI64	0x00004000
+
+#if defined(__MIPSEB__)
+#define	ELF32_MACHDEP_ENDIANNESS	ELFDATA2MSB
+#define	ELF64_MACHDEP_ENDIANNESS	ELFDATA2MSB
+#elif defined(__MIPSEL__)
+#define	ELF32_MACHDEP_ENDIANNESS	ELFDATA2LSB
+#define	ELF64_MACHDEP_ENDIANNESS	ELFDATA2LSB
+#elif !defined(HAVE_NBTOOL_CONFIG_H)
+#error neither __MIPSEL__ nor __MIPSEB__ are defined.
+#endif
+
+#ifdef _KERNEL
+#ifdef _KERNEL_OPT
+#include "opt_compat_netbsd.h"
+#endif
+#ifdef COMPAT_16
+/*
+ * Up to 1.6, the ELF dynamic loader (ld.elf_so) was not relocatable.
+ * Tell the kernel ELF exec code not to try relocating the interpreter
+ * for dynamically-linked ELF binaries.
+ */
+#define ELF_INTERP_NON_RELOCATABLE
+#endif /* COMPAT_16 */
+
+/*
+ * We need to be able to include the ELF header so we can pick out the
+ * ABI being used.
+ */
+#ifdef ELFSIZE
+#define	ELF_MD_PROBE_FUNC	ELFNAME2(mips_netbsd,probe)
+#define	ELF_MD_COREDUMP_SETUP	ELFNAME2(coredump,setup)
+#endif
+
+struct exec_package;
+
+int mips_netbsd_elf32_probe(struct lwp *, struct exec_package *, void *, char *,
+	vaddr_t *);
+void coredump_elf32_setup(struct lwp *, void *);
+
+int mips_netbsd_elf64_probe(struct lwp *, struct exec_package *, void *, char *,
+	vaddr_t *);
+void coredump_elf64_setup(struct lwp *, void *);
+#endif /* _KERNEL */
+
+#endif /* _MIPS_ELF_MACHDEP_H_ */
diff --git a/cpukit/libdl/include/arch/moxie/machine/elf_machdep.h b/cpukit/libdl/include/arch/moxie/machine/elf_machdep.h
new file mode 100644
index 0000000..3f0df23
--- /dev/null
+++ b/cpukit/libdl/include/arch/moxie/machine/elf_machdep.h
@@ -0,0 +1,15 @@
+#define ELF32_MACHDEP_ENDIANNESS		ELFDATA2MSB
+
+#define ELF32_MACHDEP_ID_CASES \
+	case EM_MOXIE: \
+		break;
+
+#define ELF32_MACHDEP_ID	EM_MOXIE
+
+#define ARCH_ELFSIZE	32
+
+#define R_MOXIE_NONE 0
+#define R_MOXIE_32 1
+#define R_MOXIE_PCREL10 2
+
+#define R_TYPE(name)		__CONCAT(R_MOXIE_,name)
diff --git a/cpukit/libdl/include/arch/nios2/machine/elf_machdep.h b/cpukit/libdl/include/arch/nios2/machine/elf_machdep.h
new file mode 100644
index 0000000..3f3c108
--- /dev/null
+++ b/cpukit/libdl/include/arch/nios2/machine/elf_machdep.h
@@ -0,0 +1,46 @@
+/*	$NetBSD: elf_machdep.h,v 1.7 2002/01/28 21:34:48 thorpej Exp $	*/
+
+#define	ELF32_MACHDEP_ENDIANNESS	ELFDATA2MSB
+#define	ELF32_MACHDEP_ID_CASES						\
+		case EM_ALTERA_NIOS2:						\
+			break;
+
+#define	ELF64_MACHDEP_ENDIANNESS	XXX	/* break compilation */
+#define	ELF64_MACHDEP_ID_CASES						\
+		/* no 64-bit ELF machine types supported */
+
+#define	ELF32_MACHDEP_ID	EM_ALTERA_NIOS2
+
+/*
+ * Machine-dependent ELF flags.  These are defined by the GNU tools.
+ */
+#define	EF_NIOS2	0x00810000
+
+#define ARCH_ELFSIZE		32	/* MD native binary size */
+
+/* NIOS2 relocation types */
+#define	R_NIOS2_NONE	0
+#define	R_NIOS2_32	1
+#define	R_NIOS2_16	2
+#define	R_NIOS2_8		3
+#define	R_NIOS2_PC32	4
+#define	R_NIOS2_PC16	5
+#define	R_NIOS2_PC8	6
+#define	R_NIOS2_GOT32	7
+#define	R_NIOS2_GOT16	8
+#define	R_NIOS2_GOT8	9
+#define	R_NIOS2_GOT32O	10
+#define	R_NIOS2_GOT16O	11
+#define	R_NIOS2_GOT8O	12
+#define	R_NIOS2_PLT32	13
+#define	R_NIOS2_PLT16	14
+#define	R_NIOS2_PLT8	15
+#define	R_NIOS2_PLT32O	16
+#define	R_NIOS2_PLT16O	17
+#define	R_NIOS2_PLT8O	18
+#define	R_NIOS2_COPY	19
+#define	R_NIOS2_GLOB_DAT	20
+#define	R_NIOS2_JMP_SLOT	21
+#define	R_NIOS2_RELATIVE	22
+
+#define	R_TYPE(name)	__CONCAT(R_NIOS2_,name)
diff --git a/cpukit/libdl/include/arch/powerpc/machine/elf_machdep.h b/cpukit/libdl/include/arch/powerpc/machine/elf_machdep.h
new file mode 100644
index 0000000..f0fdb3f
--- /dev/null
+++ b/cpukit/libdl/include/arch/powerpc/machine/elf_machdep.h
@@ -0,0 +1,105 @@
+/*	$NetBSD: elf_machdep.h,v 1.9 2011/01/15 10:00:07 matt Exp $	*/
+
+#define	ELF32_MACHDEP_ENDIANNESS	ELFDATA2MSB
+#define	ELF32_MACHDEP_ID_CASES						\
+		case EM_PPC:						\
+			break;
+
+#define	ELF64_MACHDEP_ENDIANNESS	ELFDATA2MSB
+#define	ELF64_MACHDEP_ID_CASES						\
+		case EM_PPC64:						\
+			break;
+
+#define	ELF32_MACHDEP_ID	EM_PPC
+#define	ELF64_MACHDEP_ID	EM_PPC64
+
+#ifdef _LP64
+#define ARCH_ELFSIZE		64	/* MD native binary size */
+#else
+#define ARCH_ELFSIZE		32	/* MD native binary size */
+#endif
+
+/* Specify the value of _GLOBAL_OFFSET_TABLE_ */
+#define	DT_PPC_GOT		DT_LOPROC
+
+#define	R_PPC_NONE 		0
+#define	R_PPC_32 		1
+#define	R_PPC_24 		2
+#define	R_PPC_16 		3
+#define	R_PPC_16_LO 		4
+#define	R_PPC_16_HI 		5 /* R_PPC_ADDIS */
+#define	R_PPC_16_HA 		6
+#define	R_PPC_14 		7
+#define	R_PPC_14_TAKEN 		8
+#define	R_PPC_14_NTAKEN 	9
+#define	R_PPC_REL24 		10 /* R_PPC_BRANCH */
+#define	R_PPC_REL14 		11
+#define	R_PPC_REL14_TAKEN 	12
+#define	R_PPC_REL14_NTAKEN 	13
+#define	R_PPC_GOT16 		14
+#define	R_PPC_GOT16_LO 		15
+#define	R_PPC_GOT16_HI 		16
+#define	R_PPC_GOT16_HA 		17
+#define	R_PPC_PLT24 		18
+#define	R_PPC_COPY 		19
+#define	R_PPC_GLOB_DAT 		20
+#define	R_PPC_JMP_SLOT 		21
+#define	R_PPC_RELATIVE 		22
+#define	R_PPC_LOCAL24PC 	23
+#define	R_PPC_U32 		24
+#define	R_PPC_U16 		25
+#define	R_PPC_REL32 		26
+#define	R_PPC_PLT32 		27
+#define	R_PPC_PLTREL32 		28
+#define	R_PPC_PLT16_LO 		29
+#define	R_PPC_PLT16_HI 		30
+#define	R_PPC_PLT16_HA 		31
+#define	R_PPC_SDAREL16 		32
+#define	R_PPC_SECTOFF 		33
+#define	R_PPC_SECTOFF_LO 	34
+#define	R_PPC_SECTOFF_HI	35
+#define	R_PPC_SECTOFF_HA	36
+#define	R_PPC_ADDR30 		37
+
+/* TLS relocations */
+#define	R_PPC_TLS		67
+
+#define	R_PPC_DTPMOD32		68
+#define	R_PPC_TPREL16		69
+#define	R_PPC_TPREL16_LO	70
+#define	R_PPC_TPREL16_HI	71
+#define	R_PPC_TPREL16_HA	72
+#define	R_PPC_TPREL32		73
+#define	R_PPC_DTPREL16		74
+#define	R_PPC_DTPREL16_LO	75
+#define	R_PPC_DTPREL16_HI	76
+#define	R_PPC_DTPREL16_HA	77
+#define	R_PPC_DTPREL32		78
+
+#define	R_PPC_GOT_TLSGD16	79
+#define	R_PPC_GOT_TLSGD16_LO	80
+#define	R_PPC_GOT_TLSGD16_HI	81
+#define	R_PPC_GOT_TLSGD16_HA	82
+#define	R_PPC_GOT_TLSLD16	83
+#define	R_PPC_GOT_TLSLD16_LO	84
+#define	R_PPC_GOT_TLSLD16_HI	85
+#define	R_PPC_GOT_TLSLD16_HA	86
+
+#define	R_PPC_GOT_TPREL16	87
+#define	R_PPC_GOT_TPREL16_LO	88
+#define	R_PPC_GOT_TPREL16_HI	89
+#define	R_PPC_GOT_TPREL16_HA	90
+#define	R_PPC_GOT_DTPREL16	91
+#define	R_PPC_GOT_DTPREL16_LO	92
+#define	R_PPC_GOT_DTPREL16_HI	93
+#define	R_PPC_GOT_DTPREL16_HA	94
+#define	R_PPC_TLSGD		95
+#define	R_PPC_TLSLD		96
+
+/* Used for the secure-plt PIC code sequences */
+#define	R_PPC_REL16		249
+#define	R_PPC_REL16_LO		250
+#define	R_PPC_REL16_HI		251
+#define	R_PPC_REL16_HA		252
+
+#define R_TYPE(name) 		__CONCAT(R_PPC_,name)
diff --git a/cpukit/libdl/include/arch/sparc/machine/elf_machdep.h b/cpukit/libdl/include/arch/sparc/machine/elf_machdep.h
new file mode 100644
index 0000000..e8f2b63
--- /dev/null
+++ b/cpukit/libdl/include/arch/sparc/machine/elf_machdep.h
@@ -0,0 +1,92 @@
+/*	$NetBSD: elf_machdep.h,v 1.7 2009/05/30 05:56:53 skrll Exp $	*/
+
+#define ELF32_MACHDEP_ENDIANNESS	ELFDATA2MSB
+#define	ELF32_MACHDEP_ID_CASES						\
+		case EM_SPARC:						\
+		case EM_SPARC32PLUS:					\
+			break;
+
+#define	ELF64_MACHDEP_ENDIANNESS	ELFDATA2MSB
+#define	ELF64_MACHDEP_ID_CASES						\
+		case EM_SPARC32PLUS:					\
+		case EM_SPARCV9:					\
+		/* no 64-bit ELF machine types supported */
+
+#define	ELF32_MACHDEP_ID	EM_SPARC	/* XXX right? */
+
+#define ARCH_ELFSIZE		32	/* MD native binary size */
+
+#define R_SPARC_NONE		0
+#define R_SPARC_8		1
+#define R_SPARC_16		2
+#define R_SPARC_32		3
+#define R_SPARC_DISP8		4
+#define R_SPARC_DISP16		5
+#define R_SPARC_DISP32		6
+#define R_SPARC_WDISP30		7
+#define R_SPARC_WDISP22		8
+#define R_SPARC_HI22		9
+#define R_SPARC_22		10
+#define R_SPARC_13		11
+#define R_SPARC_LO10		12
+#define R_SPARC_GOT10		13
+#define R_SPARC_GOT13		14
+#define R_SPARC_GOT22		15
+#define R_SPARC_PC10		16
+#define R_SPARC_PC22		17
+#define R_SPARC_WPLT30		18
+#define R_SPARC_COPY		19
+#define R_SPARC_GLOB_DAT	20
+#define R_SPARC_JMP_SLOT	21
+#define R_SPARC_RELATIVE	22
+#define R_SPARC_UA32		23
+#define R_SPARC_PLT32		24
+#define R_SPARC_HIPLT22		25
+#define R_SPARC_LOPLT10		26
+#define R_SPARC_PCPLT32		27
+#define R_SPARC_PCPLT22		28
+#define R_SPARC_PCPLT10		29
+#define R_SPARC_10		30
+#define R_SPARC_11		31
+#define R_SPARC_64		32
+#define R_SPARC_OLO10		33
+#define R_SPARC_HH22		34
+#define R_SPARC_HM10		35
+#define R_SPARC_LM22		36
+#define R_SPARC_PC_HH22		37
+#define R_SPARC_PC_HM10		38
+#define R_SPARC_PC_LM22		39
+#define R_SPARC_WDISP16		40
+#define R_SPARC_WDISP19		41
+#define R_SPARC_GLOB_JMP	42
+#define R_SPARC_7		43
+#define R_SPARC_5		44
+#define R_SPARC_6		45
+
+/* TLS relocations */
+#define R_SPARC_TLS_GD_HI22	56
+#define R_SPARC_TLS_GD_LO10	57
+#define R_SPARC_TLS_GD_ADD	58
+#define R_SPARC_TLS_GD_CALL	59
+#define R_SPARC_TLS_LDM_HI22	60
+#define R_SPARC_TLS_LDM_LO10	61
+#define R_SPARC_TLS_LDM_ADD	62
+#define R_SPARC_TLS_LDM_CALL	63
+#define R_SPARC_TLS_LDO_HIX22	64
+#define R_SPARC_TLS_LDO_LOX10	65
+#define R_SPARC_TLS_LDO_ADD	66
+#define R_SPARC_TLS_IE_HI22	67
+#define R_SPARC_TLS_IE_LO10	68
+#define R_SPARC_TLS_IE_LD	69
+#define R_SPARC_TLS_IE_LDX	70
+#define R_SPARC_TLS_IE_ADD	71
+#define R_SPARC_TLS_LE_HIX22	72
+#define R_SPARC_TLS_LE_LOX10	73
+#define R_SPARC_TLS_DTPMOD32	74
+#define R_SPARC_TLS_DTPMOD64	75
+#define R_SPARC_TLS_DTPOFF32	76
+#define R_SPARC_TLS_DTPOFF64	77
+#define R_SPARC_TLS_TPOFF32	78
+#define R_SPARC_TLS_TPOFF64	79
+
+#define R_TYPE(name)		__CONCAT(R_SPARC_,name)
diff --git a/cpukit/libdl/include/arch/v850/machine/elf_machdep.h b/cpukit/libdl/include/arch/v850/machine/elf_machdep.h
new file mode 100644
index 0000000..b76d149
--- /dev/null
+++ b/cpukit/libdl/include/arch/v850/machine/elf_machdep.h
@@ -0,0 +1,74 @@
+#define ELF32_MACHDEP_ENDIANNESS		ELFDATA2LSB
+
+#define ELF32_MACHDEP_ID_CASES \
+	case EM_V850: \
+		break;
+
+#define ELF32_MACHDEP_ID	EM_V850
+
+
+
+#define EF_V850_ARCH		0xf0000000
+#define E_V850_ARCH		0x00000000
+#define E_V850E_ARCH		0x10000000
+#define E_V850E1_ARCH		0x20000000
+#define E_V850E2_ARCH		0x30000000
+#define E_V850E2V3_ARCH		0x40000000
+
+#define ARCH_ELFSIZE	32
+
+
+#define		R_V850_NONE								0
+#define		R_V850_9_PCREL						1
+#define		R_V850_22_PCREL						2
+#define		R_V850_HI16_S							3
+#define		R_V850_HI16								4
+#define		R_V850_LO16								5
+#define		R_V850_ABS32							6
+#define		R_V850_16									7
+#define		R_V850_8									8
+#define		R_V850_SDA_16_16_OFFSET		9
+#define		R_V850_SDA_15_16_OFFSET		10
+#define		R_V850_ZDA_16_16_OFFSET		11
+#define		R_V850_ZDA_15_16_OFFSET		12
+#define		R_V850_TDA_6_8_OFFSET			13
+#define		R_V850_TDA_7_8_OFFSET			14
+#define		R_V850_TDA_7_7_OFFSET			15
+#define		R_V850_TDA_16_16_OFFSET		16
+#define		R_V850_TDA_4_5_OFFSET			17
+#define		R_V850_TDA_4_4_OFFSET			18
+#define		R_V850_SDA_16_16_SPLIT_OFFSET		19
+#define		R_V850_ZDA_16_16_SPLIT_OFFSET		20
+#define		R_V850_CALLT_6_7_OFFSET			21
+#define		R_V850_CALLT_16_16_OFFSET		22
+#define		R_V850_GNU_VTINHERIT				23
+#define		R_V850_GNU_VTENTRY					24
+#define		R_V850_LONGCALL							25
+#define		R_V850_LONGJUMP							26
+#define		R_V850_ALIGN								27
+#define		R_V850_REL32								28
+#define		R_V850_LO16_SPLIT_OFFSET		29
+#define		R_V850_16_PCREL							30
+#define		R_V850_17_PCREL							31
+#define		R_V850_23										32
+#define		R_V850_32_PCREL							33
+#define		R_V850_32_ABS								34
+#define		R_V850_16_SPLIT_OFFSET			35
+#define		R_V850_16_S1								36
+#define		R_V850_LO16_S1							37
+#define		R_V850_CALLT_15_16_OFFSET		38
+#define		R_V850_32_GOTPCREL					39
+#define		R_V850_16_GOT								40
+#define		R_V850_32_GOT								41
+#define		R_V850_22_PLT								42
+#define		R_V850_32_PLT								43
+#define		R_V850_COPY									44
+#define		R_V850_GLOB_DAT							45
+#define		R_V850_JMP_SLOT							46
+#define		R_V850_RELATIVE							47
+#define		R_V850_16_GOTOFF						48
+#define		R_V850_32_GOTOFF						49
+#define		R_V850_CODE									50
+#define		R_V850_DATA									51
+
+#define R_TYPE(name)		__CONCAT(R_V850_,name)
diff --git a/cpukit/libdl/include/link.h b/cpukit/libdl/include/link.h
new file mode 100644
index 0000000..c93efd9
--- /dev/null
+++ b/cpukit/libdl/include/link.h
@@ -0,0 +1,45 @@
+/*	$NetBSD: link.h,v 1.13 2008/04/28 20:22:54 martin Exp $	*/
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LINK_H_
+#define	_LINK_H_
+
+/*
+ * Pull in the correct definitions for our toolchain target.
+ */
+#ifdef __ELF__
+#include <link_elf.h>
+#else
+#include <link_aout.h>
+#endif
+
+#endif /* _LINK_H_ */
diff --git a/cpukit/libdl/include/link_elf.h b/cpukit/libdl/include/link_elf.h
new file mode 100644
index 0000000..d2691b6
--- /dev/null
+++ b/cpukit/libdl/include/link_elf.h
@@ -0,0 +1,79 @@
+/*	$NetBSD: link_elf.h,v 1.8 2009/11/04 19:28:03 pooka Exp $	*/
+
+/*
+ * This only exists for GDB.
+ */
+
+#ifndef _LINK_ELF_H_
+#define	_LINK_ELF_H_
+
+#include <sys/types.h>
+
+#include <machine/elf_machdep.h>
+#include <stdint.h>
+#include <rtems/rtl/rtl-obj-fwd.h>
+
+enum sections
+{
+  rap_text = 0,
+  rap_const = 1,
+  rap_ctor = 2,
+  rap_dtor = 3,
+  rap_data = 4,
+  rap_bss = 5,
+  rap_secs = 6
+};
+
+/**
+ * Object details.
+ */
+typedef struct
+{
+  const char* name;   /**< Section name. */
+  uint32_t    offset; /**< The offset in the elf file. */
+  uint32_t    size;   /**< The size of the section. */
+  uint32_t    rap_id; /**< Which obj does this section belongs to. */
+}section_detail;
+
+/**
+ * link map structure will be used for GDB support.
+ */
+struct link_map {
+  const char*       name;                 /**< Name of the obj. */
+  uint32_t          sec_num;              /**< The count of section. */
+  section_detail*   sec_detail;           /**< The section details. */
+  uint32_t*         sec_addr[rap_secs];   /**< The RAP section addr. */
+  uint32_t          rpathlen;             /**< The length of the path. */
+  char*             rpath;                /**< The path of object files. */
+  struct link_map*  l_next;               /**< Linked list of mapped libs. */
+  struct link_map*  l_prev;
+};
+
+/**
+ * r_debug is used to manage the debug related structures.
+ */
+struct r_debug {
+	int r_version;			      /* not used */
+	struct link_map *r_map;		/* list of loaded images */
+	enum {
+		RT_CONSISTENT,		      /* things are stable */
+		RT_ADD,			            /* adding a shared library */
+		RT_DELETE		            /* removing a shared library */
+	} r_state;
+};
+
+/*
+ * stub function. It is empty.
+ */
+void _rtld_debug_state (void);
+
+/*
+ * add link map to the list.
+ */
+int _rtld_linkmap_add (rtems_rtl_obj_t* obj);
+
+/*
+ * Remove link map from the list.
+ */
+void _rtld_linkmap_delete (rtems_rtl_obj_t* obj);
+#endif	/* _LINK_ELF_H_ */
diff --git a/cpukit/libdl/include/sys/cdefs_elf.h b/cpukit/libdl/include/sys/cdefs_elf.h
new file mode 100644
index 0000000..91903d6
--- /dev/null
+++ b/cpukit/libdl/include/sys/cdefs_elf.h
@@ -0,0 +1,152 @@
+/*	$NetBSD: cdefs_elf.h,v 1.24 2005/07/16 17:53:36 christos Exp $	*/
+
+/*
+ * Copyright (c) 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ *  Software Distribution Coordinator  or  Software.Distribution at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#ifndef _SYS_CDEFS_ELF_H_
+#define	_SYS_CDEFS_ELF_H_
+
+#ifdef __LEADING_UNDERSCORE
+#define	_C_LABEL(x)	__CONCAT(_,x)
+#define _C_LABEL_STRING(x)	"_"x
+#else
+#define	_C_LABEL(x)	x
+#define _C_LABEL_STRING(x)	x
+#endif
+
+#if __STDC__
+#define	___RENAME(x)	__asm__(___STRING(_C_LABEL(x)))
+#else
+#ifdef __LEADING_UNDERSCORE
+#define	___RENAME(x)	____RENAME(_/**/x)
+#define	____RENAME(x)	__asm__(___STRING(x))
+#else
+#define	___RENAME(x)	__asm__(___STRING(x))
+#endif
+#endif
+
+#define	__indr_reference(sym,alias)	/* nada, since we do weak refs */
+
+#if __STDC__
+#define	__strong_alias(alias,sym)	       				\
+    __asm__(".global " _C_LABEL_STRING(#alias) "\n"			\
+	    _C_LABEL_STRING(#alias) " = " _C_LABEL_STRING(#sym));
+
+#define	__weak_alias(alias,sym)						\
+    __asm__(".weak " _C_LABEL_STRING(#alias) "\n"			\
+	    _C_LABEL_STRING(#alias) " = " _C_LABEL_STRING(#sym));
+#define	__weak_extern(sym)						\
+    __asm__(".weak " _C_LABEL_STRING(#sym));
+#define	__warn_references(sym,msg)					\
+    __asm__(".section .gnu.warning." #sym "\n\t.ascii \"" msg "\"\n\t.text");
+
+#else /* !__STDC__ */
+
+#ifdef __LEADING_UNDERSCORE
+#define __weak_alias(alias,sym) ___weak_alias(_/**/alias,_/**/sym)
+#define	___weak_alias(alias,sym)					\
+    __asm__(".weak alias\nalias = sym");
+#else
+#define	__weak_alias(alias,sym)						\
+    __asm__(".weak alias\nalias = sym");
+#endif
+#ifdef __LEADING_UNDERSCORE
+#define __weak_extern(sym) ___weak_extern(_/**/sym)
+#define	___weak_extern(sym)						\
+    __asm__(".weak sym");
+#else
+#define	__weak_extern(sym)						\
+    __asm__(".weak sym");
+#endif
+#define	__warn_references(sym,msg)					\
+    __asm__(".section .gnu.warning.sym\n\t.ascii msg ; .text");
+
+#endif /* !__STDC__ */
+
+#if __STDC__
+#define	__SECTIONSTRING(_sec, _str)					\
+	__asm__(".section " #_sec "\n\t.asciz \"" _str "\"\n\t.previous")
+#else
+#define	__SECTIONSTRING(_sec, _str)					\
+	__asm__(".section _sec\n\t.asciz _str\n\t.previous")
+#endif
+
+#define	__IDSTRING(_n,_s)		__SECTIONSTRING(.ident,_s)
+
+#define	__RCSID(_s)			__IDSTRING(rcsid,_s)
+#define	__SCCSID(_s)
+#define __SCCSID2(_s)
+#if 0	/* XXX userland __COPYRIGHTs have \ns in them */
+#define	__COPYRIGHT(_s)			__SECTIONSTRING(.copyright,_s)
+#else
+#define	__COPYRIGHT(_s)							\
+	static const char copyright[]					\
+	    __attribute__((__unused__,__section__(".copyright"))) = _s
+#endif
+
+#define	__KERNEL_RCSID(_n, _s)		__RCSID(_s)
+#define	__KERNEL_SCCSID(_n, _s)
+#if 0	/* XXX see above */
+#define	__KERNEL_COPYRIGHT(_n, _s)	__COPYRIGHT(_s)
+#else
+#define	__KERNEL_COPYRIGHT(_n, _s)	__SECTIONSTRING(.copyright, _s)
+#endif
+
+#ifndef __lint__
+#define	__link_set_make_entry(set, sym)					\
+	static void const * const __link_set_##set##_sym_##sym		\
+	    __section("link_set_" #set) __used = &sym
+#define	__link_set_make_entry2(set, sym, n)				\
+	static void const * const __link_set_##set##_sym_##sym##_##n	\
+	    __section("link_set_" #set) __used = &sym[n]
+#else
+#define	__link_set_make_entry(set, sym)					\
+	extern void const * const __link_set_##set##_sym_##sym
+#define	__link_set_make_entry2(set, sym, n)				\
+	extern void const * const __link_set_##set##_sym_##sym##_##n
+#endif /* __lint__ */
+
+#define	__link_set_add_text(set, sym)	__link_set_make_entry(set, sym)
+#define	__link_set_add_rodata(set, sym)	__link_set_make_entry(set, sym)
+#define	__link_set_add_data(set, sym)	__link_set_make_entry(set, sym)
+#define	__link_set_add_bss(set, sym)	__link_set_make_entry(set, sym)
+#define	__link_set_add_text2(set, sym, n)   __link_set_make_entry2(set, sym, n)
+#define	__link_set_add_rodata2(set, sym, n) __link_set_make_entry2(set, sym, n)
+#define	__link_set_add_data2(set, sym, n)   __link_set_make_entry2(set, sym, n)
+#define	__link_set_add_bss2(set, sym, n)    __link_set_make_entry2(set, sym, n)
+
+#define	__link_set_decl(set, ptype)					\
+	extern ptype * const __start_link_set_##set[];			\
+	extern ptype * const __stop_link_set_##set[]			\
+
+#define	__link_set_start(set)	(__start_link_set_##set)
+#define	__link_set_end(set)	(__stop_link_set_##set)
+
+#define	__link_set_count(set)						\
+	(__link_set_end(set) - __link_set_start(set))
+
+#endif /* !_SYS_CDEFS_ELF_H_ */
diff --git a/cpukit/libdl/include/sys/exec_elf.h b/cpukit/libdl/include/sys/exec_elf.h
new file mode 100644
index 0000000..08da7e8
--- /dev/null
+++ b/cpukit/libdl/include/sys/exec_elf.h
@@ -0,0 +1,1097 @@
+/*	$NetBSD: exec_elf.h,v 1.102 2010/03/01 11:27:29 skrll Exp $	*/
+
+/*-
+ * Copyright (c) 1994 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_EXEC_ELF_H_
+#define	_SYS_EXEC_ELF_H_
+
+/*
+ * The current ELF ABI specification is available at:
+ *	http://www.sco.com/developers/gabi/
+ *
+ * Current header definitions are in:
+ *	http://www.sco.com/developers/gabi/latest/ch4.eheader.html
+ */
+
+#if defined(_KERNEL) || defined(_STANDALONE)
+#include <sys/types.h>
+#else
+#include <inttypes.h>
+#endif /* _KERNEL || _STANDALONE */
+
+#if defined(ELFSIZE)
+#define	CONCAT(x,y)	__CONCAT(x,y)
+#define	ELFNAME(x)	CONCAT(elf,CONCAT(ELFSIZE,CONCAT(_,x)))
+#define	ELFNAME2(x,y)	CONCAT(x,CONCAT(_elf,CONCAT(ELFSIZE,CONCAT(_,y))))
+#define	ELFNAMEEND(x)	CONCAT(x,CONCAT(_elf,ELFSIZE))
+#define	ELFDEFNNAME(x)	CONCAT(ELF,CONCAT(ELFSIZE,CONCAT(_,x)))
+#endif
+
+#if HAVE_NBTOOL_CONFIG_H
+#include <nbinclude/machine/elf_machdep.h>
+#else
+#include <machine/elf_machdep.h>
+#endif
+
+typedef	uint8_t  	Elf_Byte;
+
+typedef	uint32_t	Elf32_Addr;
+#define	ELF32_FSZ_ADDR	4
+typedef	uint32_t	Elf32_Off;
+typedef	int32_t		Elf32_SOff;
+#define	ELF32_FSZ_OFF	4
+typedef	int32_t		Elf32_Sword;
+#define	ELF32_FSZ_SWORD	4
+typedef	uint32_t	Elf32_Word;
+#define	ELF32_FSZ_WORD	4
+typedef	uint16_t	Elf32_Half;
+#define	ELF32_FSZ_HALF	2
+typedef	uint64_t	Elf32_Lword;
+#define	ELF32_FSZ_LWORD	8
+
+typedef	uint64_t	Elf64_Addr;
+#define	ELF64_FSZ_ADDR	8
+typedef	uint64_t	Elf64_Off;
+typedef	int64_t		Elf64_SOff;
+#define	ELF64_FSZ_OFF	8
+typedef	int32_t		Elf64_Shalf;
+#define	ELF64_FSZ_SHALF	4
+
+#ifndef ELF64_FSZ_SWORD
+typedef	int32_t		Elf64_Sword;
+#define	ELF64_FSZ_SWORD	4
+#endif /* ELF64_FSZ_SWORD */
+#ifndef ELF64_FSZ_WORD
+typedef	uint32_t	Elf64_Word;
+#define	ELF64_FSZ_WORD	4
+#endif /* ELF64_FSZ_WORD */
+
+typedef	int64_t		Elf64_Sxword;
+#define	ELF64_FSZ_SXWORD 8
+typedef	uint64_t	Elf64_Xword;
+#define	ELF64_FSZ_XWORD	8
+typedef	uint64_t	Elf64_Lword;
+#define	ELF64_FSZ_LWORD	8
+typedef	uint32_t	Elf64_Half;
+#define	ELF64_FSZ_HALF	4
+typedef	uint16_t	Elf64_Quarter;
+#define	ELF64_FSZ_QUARTER 2
+
+/*
+ * ELF Header
+ */
+#define	ELF_NIDENT	16
+
+typedef struct {
+	unsigned char	e_ident[ELF_NIDENT];	/* Id bytes */
+	Elf32_Half	e_type;			/* file type */
+	Elf32_Half	e_machine;		/* machine type */
+	Elf32_Word	e_version;		/* version number */
+	Elf32_Addr	e_entry;		/* entry point */
+	Elf32_Off	e_phoff;		/* Program hdr offset */
+	Elf32_Off	e_shoff;		/* Section hdr offset */
+	Elf32_Word	e_flags;		/* Processor flags */
+	Elf32_Half      e_ehsize;		/* sizeof ehdr */
+	Elf32_Half      e_phentsize;		/* Program header entry size */
+	Elf32_Half      e_phnum;		/* Number of program headers */
+	Elf32_Half      e_shentsize;		/* Section header entry size */
+	Elf32_Half      e_shnum;		/* Number of section headers */
+	Elf32_Half      e_shstrndx;		/* String table index */
+} Elf32_Ehdr;
+
+typedef struct {
+	unsigned char	e_ident[ELF_NIDENT];	/* Id bytes */
+	Elf64_Quarter	e_type;			/* file type */
+	Elf64_Quarter	e_machine;		/* machine type */
+	Elf64_Half	e_version;		/* version number */
+	Elf64_Addr	e_entry;		/* entry point */
+	Elf64_Off	e_phoff;		/* Program hdr offset */
+	Elf64_Off	e_shoff;		/* Section hdr offset */
+	Elf64_Half	e_flags;		/* Processor flags */
+	Elf64_Quarter	e_ehsize;		/* sizeof ehdr */
+	Elf64_Quarter	e_phentsize;		/* Program header entry size */
+	Elf64_Quarter	e_phnum;		/* Number of program headers */
+	Elf64_Quarter	e_shentsize;		/* Section header entry size */
+	Elf64_Quarter	e_shnum;		/* Number of section headers */
+	Elf64_Quarter	e_shstrndx;		/* String table index */
+} Elf64_Ehdr;
+
+/* e_ident offsets */
+#define	EI_MAG0		0	/* '\177' */
+#define	EI_MAG1		1	/* 'E'    */
+#define	EI_MAG2		2	/* 'L'    */
+#define	EI_MAG3		3	/* 'F'    */
+#define	EI_CLASS	4	/* File class */
+#define	EI_DATA		5	/* Data encoding */
+#define	EI_VERSION	6	/* File version */
+#define	EI_OSABI	7	/* Operating system/ABI identification */
+#define	EI_ABIVERSION	8	/* ABI version */
+#define	EI_PAD		9	/* Start of padding bytes up to EI_NIDENT*/
+#define	EI_NIDENT	16	/* First non-ident header byte */
+
+/* e_ident[EI_MAG0,EI_MAG3] */
+#define	ELFMAG0		0x7f
+#define	ELFMAG1		'E'
+#define	ELFMAG2		'L'
+#define	ELFMAG3		'F'
+#define	ELFMAG		"\177ELF"
+#define	SELFMAG		4
+
+/* e_ident[EI_CLASS] */
+#define	ELFCLASSNONE	0	/* Invalid class */
+#define	ELFCLASS32	1	/* 32-bit objects */
+#define	ELFCLASS64	2	/* 64-bit objects */
+#define	ELFCLASSNUM	3
+
+/* e_ident[EI_DATA] */
+#define	ELFDATANONE	0	/* Invalid data encoding */
+#define	ELFDATA2LSB	1	/* 2's complement values, LSB first */
+#define	ELFDATA2MSB	2	/* 2's complement values, MSB first */
+
+/* e_ident[EI_VERSION] */
+#define	EV_NONE		0	/* Invalid version */
+#define	EV_CURRENT	1	/* Current version */
+#define	EV_NUM		2
+
+/* e_ident[EI_OSABI] */
+#define	ELFOSABI_SYSV		0	/* UNIX System V ABI */
+#define	ELFOSABI_HPUX		1	/* HP-UX operating system */
+#define ELFOSABI_NETBSD		2	/* NetBSD */
+#define ELFOSABI_LINUX		3	/* GNU/Linux */
+#define ELFOSABI_HURD		4	/* GNU/Hurd */
+#define ELFOSABI_86OPEN		5	/* 86Open */
+#define ELFOSABI_SOLARIS	6	/* Solaris */
+#define ELFOSABI_MONTEREY	7	/* Monterey */
+#define ELFOSABI_IRIX		8	/* IRIX */
+#define ELFOSABI_FREEBSD	9	/* FreeBSD */
+#define ELFOSABI_TRU64		10	/* TRU64 UNIX */
+#define ELFOSABI_MODESTO	11	/* Novell Modesto */
+#define ELFOSABI_OPENBSD	12	/* OpenBSD */
+#define	ELFOSABI_OPENVMS	13	/* OpenVMS */
+#define	ELFOSABI_NSK		14	/* HP Non-Stop Kernel */
+#define	ELFOSABI_AROS		15	/* Amiga Research OS */
+/* Unofficial OSABIs follow */
+#define ELFOSABI_ARM		97	/* ARM */
+#define	ELFOSABI_STANDALONE	255	/* Standalone (embedded) application */
+
+#define	ELFOSABI_NONE		ELFOSABI_SYSV
+#define	ELFOSABI_AIX		ELFOSABI_MONTEREY
+
+/* e_type */
+#define	ET_NONE		0	/* No file type */
+#define	ET_REL		1	/* Relocatable file */
+#define	ET_EXEC		2	/* Executable file */
+#define	ET_DYN		3	/* Shared object file */
+#define	ET_CORE		4	/* Core file */
+#define	ET_NUM		5
+
+#define	ET_LOOS		0xfe00	/* Operating system specific range */
+#define	ET_HIOS		0xfeff
+#define	ET_LOPROC	0xff00	/* Processor-specific range */
+#define	ET_HIPROC	0xffff
+
+/* e_machine */
+#define	EM_NONE		0	/* No machine */
+#define	EM_M32		1	/* AT&T WE 32100 */
+#define	EM_SPARC	2	/* SPARC */
+#define	EM_386		3	/* Intel 80386 */
+#define	EM_68K		4	/* Motorola 68000 */
+#define	EM_88K		5	/* Motorola 88000 */
+#define	EM_486		6	/* Intel 80486 */
+#define	EM_860		7	/* Intel 80860 */
+#define	EM_MIPS		8	/* MIPS I Architecture */
+#define	EM_S370		9	/* Amdahl UTS on System/370 */
+#define	EM_MIPS_RS3_LE	10	/* MIPS RS3000 Little-endian */
+			/* 11-14 - Reserved */
+#define	EM_RS6000	11	/* IBM RS/6000 XXX reserved */
+#define	EM_PARISC	15	/* Hewlett-Packard PA-RISC */
+#define	EM_NCUBE	16	/* NCube XXX reserved */
+#define	EM_VPP500	17	/* Fujitsu VPP500 */
+#define	EM_SPARC32PLUS	18	/* Enhanced instruction set SPARC */
+#define	EM_960		19	/* Intel 80960 */
+#define	EM_PPC		20	/* PowerPC */
+#define	EM_PPC64	21	/* 64-bit PowerPC */
+			/* 22-35 - Reserved */
+#define	EM_S390		22	/* System/390 XXX reserved */
+#define	EM_V800		36	/* NEC V800 */
+#define	EM_FR20		37	/* Fujitsu FR20 */
+#define	EM_RH32		38	/* TRW RH-32 */
+#define	EM_RCE		39	/* Motorola RCE */
+#define	EM_ARM		40	/* Advanced RISC Machines ARM */
+#define	EM_ALPHA	41	/* DIGITAL Alpha */
+#define	EM_SH		42	/* Hitachi Super-H */
+#define	EM_SPARCV9	43	/* SPARC Version 9 */
+#define	EM_TRICORE	44	/* Siemens Tricore */
+#define	EM_ARC		45	/* Argonaut RISC Core */
+#define	EM_H8_300	46	/* Hitachi H8/300 */
+#define	EM_H8_300H	47	/* Hitachi H8/300H */
+#define	EM_H8S		48	/* Hitachi H8S */
+#define	EM_H8_500	49	/* Hitachi H8/500 */
+#define	EM_IA_64	50	/* Intel Merced Processor */
+#define	EM_MIPS_X	51	/* Stanford MIPS-X */
+#define	EM_COLDFIRE	52	/* Motorola Coldfire */
+#define	EM_68HC12	53	/* Motorola MC68HC12 */
+#define	EM_MMA		54	/* Fujitsu MMA Multimedia Accelerator */
+#define	EM_PCP		55	/* Siemens PCP */
+#define	EM_NCPU		56	/* Sony nCPU embedded RISC processor */
+#define	EM_NDR1		57	/* Denso NDR1 microprocessor */
+#define	EM_STARCORE	58	/* Motorola Star*Core processor */
+#define	EM_ME16		59	/* Toyota ME16 processor */
+#define	EM_ST100	60	/* STMicroelectronics ST100 processor */
+#define	EM_TINYJ	61	/* Advanced Logic Corp. TinyJ embedded family processor */
+#define	EM_X86_64	62	/* AMD x86-64 architecture */
+#define	EM_PDSP		63	/* Sony DSP Processor */
+#define	EM_PDP10	64	/* Digital Equipment Corp. PDP-10 */
+#define	EM_PDP11	65	/* Digital Equipment Corp. PDP-11 */
+#define	EM_FX66		66	/* Siemens FX66 microcontroller */
+#define	EM_ST9PLUS	67	/* STMicroelectronics ST9+ 8/16 bit microcontroller */
+#define	EM_ST7		68	/* STMicroelectronics ST7 8-bit microcontroller */
+#define	EM_68HC16	69	/* Motorola MC68HC16 Microcontroller */
+#define	EM_68HC11	70	/* Motorola MC68HC11 Microcontroller */
+#define	EM_68HC08	71	/* Motorola MC68HC08 Microcontroller */
+#define	EM_68HC05	72	/* Motorola MC68HC05 Microcontroller */
+#define	EM_SVX		73	/* Silicon Graphics SVx */
+#define	EM_ST19		74	/* STMicroelectronics ST19 8-bit CPU */
+#define	EM_VAX		75	/* Digital VAX */
+#define	EM_CRIS		76	/* Axis Communications 32-bit embedded processor */
+#define	EM_JAVELIN	77	/* Infineon Technologies 32-bit embedded CPU */
+#define	EM_FIREPATH	78	/* Element 14 64-bit DSP processor */
+#define	EM_ZSP		79	/* LSI Logic's 16-bit DSP processor */
+#define	EM_MMIX		80	/* Donald Knuth's educational 64-bit processor */
+#define	EM_HUANY	81	/* Harvard's machine-independent format */
+#define	EM_PRISM	82	/* SiTera Prism */
+#define	EM_AVR		83	/* Atmel AVR 8-bit microcontroller */
+#define	EM_FR30		84	/* Fujitsu FR30 */
+#define	EM_D10V		85	/* Mitsubishi D10V */
+#define	EM_D30V		86	/* Mitsubishi D30V */
+#define	EM_V850		87	/* NEC v850 */
+#define	EM_M32R		88	/* Mitsubishi M32R */
+#define	EM_MN10300	89	/* Matsushita MN10300 */
+#define	EM_MN10200	90	/* Matsushita MN10200 */
+#define	EM_PJ		91	/* picoJava */
+#define	EM_OPENRISC	92	/* OpenRISC 32-bit embedded processor */
+#define	EM_ARC_A5	93	/* ARC Cores Tangent-A5 */
+#define	EM_XTENSA	94	/* Tensilica Xtensa Architecture */
+#define	EM_VIDEOCORE	95	/* Alphamosaic VideoCore processor */
+#define	EM_TMM_GPP	96	/* Thompson Multimedia General Purpose Processor */
+#define	EM_NS32K	97	/* National Semiconductor 32000 series */
+#define	EM_TPC		98	/* Tenor Network TPC processor */
+#define	EM_SNP1K	99	/* Trebia SNP 1000 processor */
+#define	EM_ST200	100	/* STMicroelectronics ST200 microcontroller */
+#define	EM_IP2K		101	/* Ubicom IP2xxx microcontroller family */
+#define	EM_MAX		102	/* MAX processor */
+#define	EM_CR		103	/* National Semiconductor CompactRISC micorprocessor */
+#define	EM_F2MC16	104	/* Fujitsu F2MC16 */
+#define	EM_MSP430	105	/* Texas Instruments MSP430 */
+#define	EM_BLACKFIN	106	/* Analog Devices Blackfin DSP */
+#define	EM_SE_C33	107	/* Seiko Epson S1C33 family */
+#define	EM_SEP		108	/* Sharp embedded microprocessor */
+#define	EM_ARCA		109	/* Arca RISC microprocessor */
+#define	EM_UNICORE	110	/* UNICORE from PKU-Unity Ltd. and MPRC Peking University */
+#define EM_EXCESS       111     /* eXcess: 16/32/64-bit configurable embedded CPU */
+#define EM_DXP          112     /* Icera Semiconductor Inc. Deep Execution Processor */
+#define EM_ALTERA_NIOS2 113     /* Altera Nios II soft-core processor */
+#define EM_CRX          114     /* National Semiconductor CRX */
+#define EM_XGATE        115     /* Motorola XGATE embedded processor */
+#define EM_C166         116     /* Infineon C16x/XC16x processor */
+#define EM_M16C         117     /* Renesas M16C series microprocessors */
+#define EM_DSPIC30F     118     /* Microchip Technology dsPIC30F Digital Signal Controller */
+#define EM_CE           119     /* Freescale Communication Engine RISC core */
+#define EM_M32C         120     /* Renesas M32C series microprocessors */
+
+#define EM_LATTICEMICO32 138    /* RICS processor for Lattice FPGA architecture */
+
+#define EM_MICROBLAZE   189     /* Xilinx MicroBlaze 32-bit RISC soft processor core */
+
+#define EM_MOXIE  0xFEED
+
+/* Unofficial machine types follow */
+#define	EM_AVR32	6317	/* used by NetBSD/avr32 */
+#define	EM_ALPHA_EXP	36902	/* used by NetBSD/alpha; obsolete */
+#define	EM_NUM		36903
+
+/*
+ * Program Header
+ */
+typedef struct {
+	Elf32_Word	p_type;		/* entry type */
+	Elf32_Off	p_offset;	/* offset */
+	Elf32_Addr	p_vaddr;	/* virtual address */
+	Elf32_Addr	p_paddr;	/* physical address */
+	Elf32_Word	p_filesz;	/* file size */
+	Elf32_Word	p_memsz;	/* memory size */
+	Elf32_Word	p_flags;	/* flags */
+	Elf32_Word	p_align;	/* memory & file alignment */
+} Elf32_Phdr;
+
+typedef struct {
+	Elf64_Half	p_type;		/* entry type */
+	Elf64_Half	p_flags;	/* flags */
+	Elf64_Off	p_offset;	/* offset */
+	Elf64_Addr	p_vaddr;	/* virtual address */
+	Elf64_Addr	p_paddr;	/* physical address */
+	Elf64_Xword	p_filesz;	/* file size */
+	Elf64_Xword	p_memsz;	/* memory size */
+	Elf64_Xword	p_align;	/* memory & file alignment */
+} Elf64_Phdr;
+
+/* p_type */
+#define	PT_NULL		0		/* Program header table entry unused */
+#define	PT_LOAD		1		/* Loadable program segment */
+#define	PT_DYNAMIC	2		/* Dynamic linking information */
+#define	PT_INTERP	3		/* Program interpreter */
+#define	PT_NOTE		4		/* Auxiliary information */
+#define	PT_SHLIB	5		/* Reserved, unspecified semantics */
+#define	PT_PHDR		6		/* Entry for header table itself */
+#define	PT_NUM		7
+
+#define	PT_LOOS         0x60000000	/* OS-specific range */
+#define	PT_HIOS         0x6fffffff
+#define	PT_LOPROC	0x70000000	/* Processor-specific range */
+#define	PT_HIPROC	0x7fffffff
+
+#define	PT_MIPS_REGINFO	0x70000000
+
+/* p_flags */
+#define	PF_R		0x4	/* Segment is readable */
+#define	PF_W		0x2	/* Segment is writable */
+#define	PF_X		0x1	/* Segment is executable */
+
+#define	PF_MASKOS	0x0ff00000	/* Operating system specific values */
+#define	PF_MASKPROC	0xf0000000	/* Processor-specific values */
+
+/* Extended program header index. */
+#define	PN_XNUM		0xffff
+
+/*
+ * Section Headers
+ */
+typedef struct {
+	Elf32_Word	sh_name;	/* section name (.shstrtab index) */
+	Elf32_Word	sh_type;	/* section type */
+	Elf32_Word	sh_flags;	/* section flags */
+	Elf32_Addr	sh_addr;	/* virtual address */
+	Elf32_Off	sh_offset;	/* file offset */
+	Elf32_Word	sh_size;	/* section size */
+	Elf32_Word	sh_link;	/* link to another */
+	Elf32_Word	sh_info;	/* misc info */
+	Elf32_Word	sh_addralign;	/* memory alignment */
+	Elf32_Word	sh_entsize;	/* table entry size */
+} Elf32_Shdr;
+
+typedef struct {
+	Elf64_Half	sh_name;	/* section name (.shstrtab index) */
+	Elf64_Half	sh_type;	/* section type */
+	Elf64_Xword	sh_flags;	/* section flags */
+	Elf64_Addr	sh_addr;	/* virtual address */
+	Elf64_Off	sh_offset;	/* file offset */
+	Elf64_Xword	sh_size;	/* section size */
+	Elf64_Half	sh_link;	/* link to another */
+	Elf64_Half	sh_info;	/* misc info */
+	Elf64_Xword	sh_addralign;	/* memory alignment */
+	Elf64_Xword	sh_entsize;	/* table entry size */
+} Elf64_Shdr;
+
+/* sh_type */
+#define	SHT_NULL	0		/* Section header table entry unused */
+#define	SHT_PROGBITS	1		/* Program information */
+#define	SHT_SYMTAB	2		/* Symbol table */
+#define	SHT_STRTAB	3		/* String table */
+#define	SHT_RELA	4		/* Relocation information w/ addend */
+#define	SHT_HASH	5		/* Symbol hash table */
+#define	SHT_DYNAMIC	6		/* Dynamic linking information */
+#define	SHT_NOTE	7		/* Auxiliary information */
+#define	SHT_NOBITS	8		/* No space allocated in file image */
+#define	SHT_REL		9		/* Relocation information w/o addend */
+#define	SHT_SHLIB	10		/* Reserved, unspecified semantics */
+#define	SHT_DYNSYM	11		/* Symbol table for dynamic linker */
+#define	SHT_INIT_ARRAY	14		/* Initialization function pointers */
+#define	SHT_FINI_ARRAY	15		/* Termination function pointers */
+#define	SHT_PREINIT_ARRAY 16		/* Pre-initialization function ptrs */
+#define	SHT_GROUP	17		/* Section group */
+#define	SHT_SYMTAB_SHNDX 18		/* Section indexes (see SHN_XINDEX) */
+#define	SHT_NUM		19
+
+#define	SHT_LOOS	0x60000000	/* Operating system specific range */
+#define	SHT_SUNW_move	0x6ffffffa
+#define	SHT_SUNW_syminfo 0x6ffffffc
+#define SHT_SUNW_verdef	0x6ffffffd	/* Versions defined by file */
+#define	SHT_GNU_verdef	SHT_SUNW_verdef
+#define SHT_SUNW_verneed 0x6ffffffe	/* Versions needed by file */
+#define	SHT_GNU_verneed	SHT_SUNW_verneed
+#define SHT_SUNW_versym	0x6fffffff	/* Symbol versions */
+#define	SHT_GNU_versym	SHT_SUNW_versym
+#define	SHT_HIOS	0x6fffffff
+#define	SHT_LOPROC	0x70000000	/* Processor-specific range */
+#define	SHT_AMD64_UNWIND 0x70000001	/* unwind information */
+#define	SHT_HIPROC	0x7fffffff
+#define	SHT_LOUSER	0x80000000	/* Application-specific range */
+#define	SHT_HIUSER	0xffffffff
+
+/* sh_flags */
+#define	SHF_WRITE	0x1		/* Section contains writable data */
+#define	SHF_ALLOC	0x2		/* Section occupies memory */
+#define	SHF_EXECINSTR	0x4		/* Section contains executable insns */
+
+#define	SHF_MASKOS	0x0f000000	/* Operating system specific values */
+#define	SHF_MASKPROC	0xf0000000	/* Processor-specific values */
+
+/*
+ * Symbol Table
+ */
+typedef struct {
+	Elf32_Word	st_name;	/* Symbol name (.strtab index) */
+	Elf32_Word	st_value;	/* value of symbol */
+	Elf32_Word	st_size;	/* size of symbol */
+	Elf_Byte	st_info;	/* type / binding attrs */
+	Elf_Byte	st_other;	/* unused */
+	Elf32_Half	st_shndx;	/* section index of symbol */
+} Elf32_Sym;
+
+typedef struct {
+	Elf64_Half	st_name;	/* Symbol name (.strtab index) */
+	Elf_Byte	st_info;	/* type / binding attrs */
+	Elf_Byte	st_other;	/* unused */
+	Elf64_Quarter	st_shndx;	/* section index of symbol */
+	Elf64_Addr	st_value;	/* value of symbol */
+	Elf64_Xword	st_size;	/* size of symbol */
+} Elf64_Sym;
+
+/* Symbol Table index of the undefined symbol */
+#define	ELF_SYM_UNDEFINED	0
+
+#define STN_UNDEF		0	/* undefined index */
+
+/* st_info: Symbol Bindings */
+#define	STB_LOCAL		0	/* local symbol */
+#define	STB_GLOBAL		1	/* global symbol */
+#define	STB_WEAK		2	/* weakly defined global symbol */
+#define	STB_NUM			3
+
+#define	STB_LOOS		10	/* Operating system specific range */
+#define	STB_HIOS		12
+#define	STB_LOPROC		13	/* Processor-specific range */
+#define	STB_HIPROC		15
+
+/* st_info: Symbol Types */
+#define	STT_NOTYPE		0	/* Type not specified */
+#define	STT_OBJECT		1	/* Associated with a data object */
+#define	STT_FUNC		2	/* Associated with a function */
+#define	STT_SECTION		3	/* Associated with a section */
+#define	STT_FILE		4	/* Associated with a file name */
+#define	STT_COMMON		5	/* Uninitialised common block */
+#define	STT_TLS			6	/* Thread local data object */
+#define	STT_NUM			7
+
+#define	STT_LOOS		10	/* Operating system specific range */
+#define	STT_HIOS		12
+#define	STT_LOPROC		13	/* Processor-specific range */
+#define	STT_HIPROC		15
+
+/* st_other: Visibility Types */
+#define	STV_DEFAULT		0	/* use binding type */
+#define	STV_INTERNAL		1	/* not referenced from outside */
+#define	STV_HIDDEN		2	/* not visible, may be used via ptr */
+#define	STV_PROTECTED		3	/* visible, not preemptible */
+#define	STV_EXPORTED		4
+#define	STV_SINGLETON		5
+#define	STV_ELIMINATE		6
+
+/* st_info/st_other utility macros */
+#define	ELF_ST_BIND(info)		((uint32_t)(info) >> 4)
+#define	ELF_ST_TYPE(info)		((uint32_t)(info) & 0xf)
+#define	ELF_ST_INFO(bind,type)		((Elf_Byte)(((bind) << 4) | \
+					 ((type) & 0xf)))
+#define	ELF_ST_VISIBILITY(other)	((uint32_t)(other) & 3)
+
+/*
+ * Special section indexes
+ */
+#define	SHN_UNDEF	0		/* Undefined section */
+
+#define	SHN_LORESERVE	0xff00		/* Reserved range */
+#define	SHN_ABS		0xfff1		/*  Absolute symbols */
+#define	SHN_COMMON	0xfff2		/*  Common symbols */
+#define	SHN_XINDEX	0xffff		/* Escape -- index stored elsewhere */
+#define	SHN_HIRESERVE	0xffff
+
+#define	SHN_LOPROC	0xff00		/* Processor-specific range */
+#define	SHN_HIPROC	0xff1f
+#define	SHN_LOOS	0xff20		/* Operating system specific range */
+#define	SHN_HIOS	0xff3f
+
+#define	SHN_MIPS_ACOMMON 0xff00
+#define	SHN_MIPS_TEXT	0xff01
+#define	SHN_MIPS_DATA	0xff02
+#define	SHN_MIPS_SCOMMON 0xff03
+
+/*
+ * Relocation Entries
+ */
+typedef struct {
+	Elf32_Word	r_offset;	/* where to do it */
+	Elf32_Word	r_info;		/* index & type of relocation */
+} Elf32_Rel;
+
+typedef struct {
+	Elf32_Word	r_offset;	/* where to do it */
+	Elf32_Word	r_info;		/* index & type of relocation */
+	Elf32_Sword	r_addend;	/* adjustment value */
+} Elf32_Rela;
+
+/* r_info utility macros */
+#define	ELF32_R_SYM(info)	((info) >> 8)
+#define	ELF32_R_TYPE(info)	((info) & 0xff)
+#define	ELF32_R_INFO(sym, type)	(((sym) << 8) + (unsigned char)(type))
+
+typedef struct {
+	Elf64_Addr	r_offset;	/* where to do it */
+	Elf64_Xword	r_info;		/* index & type of relocation */
+} Elf64_Rel;
+
+typedef struct {
+	Elf64_Addr	r_offset;	/* where to do it */
+	Elf64_Xword	r_info;		/* index & type of relocation */
+	Elf64_Sxword	r_addend;	/* adjustment value */
+} Elf64_Rela;
+
+/* r_info utility macros */
+#define	ELF64_R_SYM(info)	((info) >> 32)
+#define	ELF64_R_TYPE(info)	((info) & 0xffffffff)
+#define	ELF64_R_INFO(sym,type)	(((sym) << 32) + (type))
+
+/*
+ * Move entries
+ */
+typedef struct {
+	Elf32_Lword	m_value;	/* symbol value */
+	Elf32_Word	m_info;		/* size + index */
+	Elf32_Word	m_poffset;	/* symbol offset */
+	Elf32_Half	m_repeat;	/* repeat count */
+	Elf32_Half	m_stride;	/* stride info */
+} Elf32_Move;
+
+#define	ELF32_M_SYM(info)	((info) >> 8)
+#define	ELF32_M_SIZE(info)	(info) & 0xff)
+#define	ELF32_M_INFO(sym, size)	(((sym) << 8) + (unsigned char)(size))
+
+typedef struct {
+	Elf64_Lword	m_value;	/* symbol value */
+	Elf64_Xword	m_info;		/* size + index */
+	Elf64_Xword	m_poffset;	/* symbol offset */
+	Elf64_Half	m_repeat;	/* repeat count */
+	Elf64_Half	m_stride;	/* stride info */
+} Elf64_Move;
+
+#define	ELF64_M_SYM(info)	((info) >> 8)
+#define	ELF64_M_SIZE(info)	(info) & 0xff)
+#define	ELF64_M_INFO(sym, size)	(((sym) << 8) + (unsigned char)(size))
+
+/*
+ * Hardware/software capabilities entry
+ */
+typedef struct {
+	Elf32_Word	c_tag;		/* entry tag value */
+	union {
+	    Elf32_Addr	c_ptr;
+	    Elf32_Word	c_val;
+	} c_un;
+} Elf32_Cap;
+
+typedef struct {
+	Elf64_Xword	c_tag;		/* entry tag value */
+	union {
+	    Elf64_Addr	c_ptr;
+	    Elf64_Xword	c_val;
+	} c_un;
+} Elf64_Cap;
+
+/*
+ * Dynamic Section structure array
+ */
+typedef struct {
+	Elf32_Word	d_tag;		/* entry tag value */
+	union {
+	    Elf32_Addr	d_ptr;
+	    Elf32_Word	d_val;
+	} d_un;
+} Elf32_Dyn;
+
+typedef struct {
+	Elf64_Xword	d_tag;		/* entry tag value */
+	union {
+	    Elf64_Addr	d_ptr;
+	    Elf64_Xword	d_val;
+	} d_un;
+} Elf64_Dyn;
+
+/* d_tag */
+#define	DT_NULL		0	/* Marks end of dynamic array */
+#define	DT_NEEDED	1	/* Name of needed library (DT_STRTAB offset) */
+#define	DT_PLTRELSZ	2	/* Size, in bytes, of relocations in PLT */
+#define	DT_PLTGOT	3	/* Address of PLT and/or GOT */
+#define	DT_HASH		4	/* Address of symbol hash table */
+#define	DT_STRTAB	5	/* Address of string table */
+#define	DT_SYMTAB	6	/* Address of symbol table */
+#define	DT_RELA		7	/* Address of Rela relocation table */
+#define	DT_RELASZ	8	/* Size, in bytes, of DT_RELA table */
+#define	DT_RELAENT	9	/* Size, in bytes, of one DT_RELA entry */
+#define	DT_STRSZ	10	/* Size, in bytes, of DT_STRTAB table */
+#define	DT_SYMENT	11	/* Size, in bytes, of one DT_SYMTAB entry */
+#define	DT_INIT		12	/* Address of initialization function */
+#define	DT_FINI		13	/* Address of termination function */
+#define	DT_SONAME	14	/* Shared object name (DT_STRTAB offset) */
+#define	DT_RPATH	15	/* Library search path (DT_STRTAB offset) */
+#define	DT_SYMBOLIC	16	/* Start symbol search within local object */
+#define	DT_REL		17	/* Address of Rel relocation table */
+#define	DT_RELSZ	18	/* Size, in bytes, of DT_REL table */
+#define	DT_RELENT	19	/* Size, in bytes, of one DT_REL entry */
+#define	DT_PLTREL	20 	/* Type of PLT relocation entries */
+#define	DT_DEBUG	21	/* Used for debugging; unspecified */
+#define	DT_TEXTREL	22	/* Relocations might modify non-writable seg */
+#define	DT_JMPREL	23	/* Address of relocations associated with PLT */
+#define	DT_BIND_NOW	24	/* Process all relocations at load-time */
+#define	DT_INIT_ARRAY	25	/* Address of initialization function array */
+#define	DT_FINI_ARRAY	26	/* Size, in bytes, of DT_INIT_ARRAY array */
+#define	DT_INIT_ARRAYSZ	27	/* Address of termination function array */
+#define	DT_FINI_ARRAYSZ	28	/* Size, in bytes, of DT_FINI_ARRAY array*/
+#define	DT_NUM		29
+
+#define	DT_LOOS		0x60000000	/* Operating system specific range */
+#define DT_VERSYM	0x6ffffff0	/* Symbol versions */
+#define	DT_FLAGS_1	0x6ffffffb	/* ELF dynamic flags */
+#define DT_VERDEF	0x6ffffffc	/* Versions defined by file */
+#define DT_VERDEFNUM	0x6ffffffd	/* Number of versions defined by file */
+#define DT_VERNEED	0x6ffffffe	/* Versions needed by file */
+#define DT_VERNEEDNUM	0x6fffffff	/* Number of versions needed by file */
+#define	DT_HIOS		0x6fffffff
+#define	DT_LOPROC	0x70000000	/* Processor-specific range */
+#define	DT_HIPROC	0x7fffffff
+
+/* Flag values for DT_FLAGS_1 (incomplete) */
+#define	DF_1_INITFIRST	0x00000020	/* Object's init/fini take priority */
+
+/*
+ * Auxiliary Vectors
+ */
+typedef struct {
+	Elf32_Word	a_type;				/* 32-bit id */
+	Elf32_Word	a_v;				/* 32-bit id */
+} Aux32Info;
+
+typedef struct {
+	Elf64_Half	a_type;				/* 32-bit id */
+	Elf64_Xword	a_v;				/* 64-bit id */
+} Aux64Info;
+
+/* a_type */
+#define	AT_NULL		0	/* Marks end of array */
+#define	AT_IGNORE	1	/* No meaning, a_un is undefined */
+#define	AT_EXECFD	2	/* Open file descriptor of object file */
+#define	AT_PHDR		3	/* &phdr[0] */
+#define	AT_PHENT	4	/* sizeof(phdr[0]) */
+#define	AT_PHNUM	5	/* # phdr entries */
+#define	AT_PAGESZ	6	/* PAGESIZE */
+#define	AT_BASE		7	/* Interpreter base addr */
+#define	AT_FLAGS	8	/* Processor flags */
+#define	AT_ENTRY	9	/* Entry address of executable */
+#define	AT_DCACHEBSIZE	10	/* Data cache block size */
+#define	AT_ICACHEBSIZE	11	/* Instruction cache block size */
+#define	AT_UCACHEBSIZE	12	/* Unified cache block size */
+
+	/* Vendor specific */
+#define	AT_MIPS_NOTELF	10	/* XXX a_val != 0 -> MIPS XCOFF executable */
+
+#define	AT_EUID		2000	/* euid (solaris compatible numbers) */
+#define	AT_RUID		2001	/* ruid (solaris compatible numbers) */
+#define	AT_EGID		2002	/* egid (solaris compatible numbers) */
+#define	AT_RGID		2003	/* rgid (solaris compatible numbers) */
+
+	/* Solaris kernel specific */
+#define	AT_SUN_LDELF	2004	/* dynamic linker's ELF header */
+#define	AT_SUN_LDSHDR	2005	/* dynamic linker's section header */
+#define	AT_SUN_LDNAME	2006	/* dynamic linker's name */
+#define	AT_SUN_LPGSIZE	2007	/* large pagesize */
+
+	/* Other information */
+#define	AT_SUN_PLATFORM	2008	/* sysinfo(SI_PLATFORM) */
+#define	AT_SUN_HWCAP	2009	/* process hardware capabilities */
+#define	AT_SUN_IFLUSH	2010	/* do we need to flush the instruction cache? */
+#define	AT_SUN_CPU	2011	/* CPU name */
+	/* ibcs2 emulation band aid */
+#define	AT_SUN_EMUL_ENTRY 2012	/* coff entry point */
+#define	AT_SUN_EMUL_EXECFD 2013	/* coff file descriptor */
+	/* Executable's fully resolved name */
+#define	AT_SUN_EXECNAME	2014
+
+/*
+ * Note Headers
+ */
+typedef struct {
+	Elf32_Word n_namesz;
+	Elf32_Word n_descsz;
+	Elf32_Word n_type;
+} Elf32_Nhdr;
+
+typedef struct {
+	Elf64_Half n_namesz;
+	Elf64_Half n_descsz;
+	Elf64_Half n_type;
+} Elf64_Nhdr;
+
+#define	ELF_NOTE_TYPE_ABI_TAG		1
+
+/* GNU-specific note name and description sizes */
+#define	ELF_NOTE_ABI_NAMESZ		4
+#define	ELF_NOTE_ABI_DESCSZ		16
+/* GNU-specific note name */
+#define	ELF_NOTE_ABI_NAME		"GNU\0"
+
+/* GNU-specific OS/version value stuff */
+#define	ELF_NOTE_ABI_OS_LINUX		0
+#define	ELF_NOTE_ABI_OS_HURD		1
+#define	ELF_NOTE_ABI_OS_SOLARIS		2
+
+/* NetBSD-specific note type: Emulation name.  desc is emul name string. */
+#define	ELF_NOTE_TYPE_NETBSD_TAG	1
+/* NetBSD-specific note name and description sizes */
+#define	ELF_NOTE_NETBSD_NAMESZ		7
+#define	ELF_NOTE_NETBSD_DESCSZ		4
+/* NetBSD-specific note name */
+#define	ELF_NOTE_NETBSD_NAME		"NetBSD\0\0"
+
+/* NetBSD-specific note type: Checksum.  There should be 1 NOTE per PT_LOAD
+   section.  desc is a tuple of <phnum>(16),<chk-type>(16),<chk-value>. */
+#define	ELF_NOTE_TYPE_CHECKSUM_TAG	2
+#define	ELF_NOTE_CHECKSUM_CRC32		1
+#define	ELF_NOTE_CHECKSUM_MD5		2
+#define	ELF_NOTE_CHECKSUM_SHA1		3
+#define	ELF_NOTE_CHECKSUM_SHA256	4
+
+/* NetBSD-specific note type: PaX.  There should be 1 NOTE per executable.
+   section.  desc is a 32 bit bitmask */
+#define ELF_NOTE_TYPE_PAX_TAG		3
+#define	ELF_NOTE_PAX_MPROTECT		0x01	/* Force enable Mprotect */
+#define	ELF_NOTE_PAX_NOMPROTECT		0x02	/* Force disable Mprotect */
+#define	ELF_NOTE_PAX_GUARD		0x04	/* Force enable Segvguard */
+#define	ELF_NOTE_PAX_NOGUARD		0x08	/* Force disable Servguard */
+#define	ELF_NOTE_PAX_ASLR		0x10	/* Force enable ASLR */
+#define	ELF_NOTE_PAX_NOASLR		0x20	/* Force disable ASLR */
+#define ELF_NOTE_PAX_NAMESZ		4
+#define ELF_NOTE_PAX_NAME		"PaX\0"
+#define ELF_NOTE_PAX_DESCSZ		4
+
+/*
+ * NetBSD-specific core file information.
+ *
+ * NetBSD ELF core files use notes to provide information about
+ * the process's state.  The note name is "NetBSD-CORE" for
+ * information that is global to the process, and "NetBSD-CORE at nn",
+ * where "nn" is the lwpid of the LWP that the information belongs
+ * to (such as register state).
+ *
+ * We use the following note identifiers:
+ *
+ *	ELF_NOTE_NETBSD_CORE_PROCINFO
+ *		Note is a "netbsd_elfcore_procinfo" structure.
+ *
+ * We also use ptrace(2) request numbers (the ones that exist in
+ * machine-dependent space) to identify register info notes.  The
+ * info in such notes is in the same format that ptrace(2) would
+ * export that information.
+ *
+ * Please try to keep the members of this structure nicely aligned,
+ * and if you add elements, add them to the end and bump the version.
+ */
+
+#define	ELF_NOTE_NETBSD_CORE_NAME	"NetBSD-CORE"
+
+#define	ELF_NOTE_NETBSD_CORE_PROCINFO	1
+
+#define	NETBSD_ELFCORE_PROCINFO_VERSION	1
+
+struct netbsd_elfcore_procinfo {
+	/* Version 1 fields start here. */
+	uint32_t	cpi_version;	/* netbsd_elfcore_procinfo version */
+	uint32_t	cpi_cpisize;	/* sizeof(netbsd_elfcore_procinfo) */
+	uint32_t	cpi_signo;	/* killing signal */
+	uint32_t	cpi_sigcode;	/* signal code */
+	uint32_t	cpi_sigpend[4];	/* pending signals */
+	uint32_t	cpi_sigmask[4];	/* blocked signals */
+	uint32_t	cpi_sigignore[4];/* blocked signals */
+	uint32_t	cpi_sigcatch[4];/* blocked signals */
+	int32_t		cpi_pid;	/* process ID */
+	int32_t		cpi_ppid;	/* parent process ID */
+	int32_t		cpi_pgrp;	/* process group ID */
+	int32_t		cpi_sid;	/* session ID */
+	uint32_t	cpi_ruid;	/* real user ID */
+	uint32_t	cpi_euid;	/* effective user ID */
+	uint32_t	cpi_svuid;	/* saved user ID */
+	uint32_t	cpi_rgid;	/* real group ID */
+	uint32_t	cpi_egid;	/* effective group ID */
+	uint32_t	cpi_svgid;	/* saved group ID */
+	uint32_t	cpi_nlwps;	/* number of LWPs */
+	int8_t		cpi_name[32];	/* copy of p->p_comm */
+	/* Add version 2 fields below here. */
+	int32_t		cpi_siglwp;	/* LWP target of killing signal */
+};
+
+#if defined(ELFSIZE) && (ELFSIZE == 32)
+#define	Elf_Ehdr	Elf32_Ehdr
+#define	Elf_Phdr	Elf32_Phdr
+#define	Elf_Shdr	Elf32_Shdr
+#define	Elf_Sym		Elf32_Sym
+#define	Elf_Rel		Elf32_Rel
+#define	Elf_Rela	Elf32_Rela
+#define	Elf_Dyn		Elf32_Dyn
+#define	Elf_Word	Elf32_Word
+#define	Elf_Sword	Elf32_Sword
+#define	Elf_Addr	Elf32_Addr
+#define	Elf_Off		Elf32_Off
+#define	Elf_SOff	Elf32_SOff
+#define	Elf_Nhdr	Elf32_Nhdr
+
+#define	ELF_R_SYM	ELF32_R_SYM
+#define	ELF_R_TYPE	ELF32_R_TYPE
+#define	ELFCLASS	ELFCLASS32
+
+#define	AuxInfo		Aux32Info
+#elif defined(ELFSIZE) && (ELFSIZE == 64)
+#define	Elf_Ehdr	Elf64_Ehdr
+#define	Elf_Phdr	Elf64_Phdr
+#define	Elf_Shdr	Elf64_Shdr
+#define	Elf_Sym		Elf64_Sym
+#define	Elf_Rel		Elf64_Rel
+#define	Elf_Rela	Elf64_Rela
+#define	Elf_Dyn		Elf64_Dyn
+#define	Elf_Word	Elf64_Word
+#define	Elf_Sword	Elf64_Sword
+#define	Elf_Addr	Elf64_Addr
+#define	Elf_Off		Elf64_Off
+#define	Elf_SOff	Elf64_SOff
+#define	Elf_Nhdr	Elf64_Nhdr
+
+#define	ELF_R_SYM	ELF64_R_SYM
+#define	ELF_R_TYPE	ELF64_R_TYPE
+#define	ELFCLASS	ELFCLASS64
+
+#define	AuxInfo		Aux64Info
+#endif
+
+#define	ELF32_ST_BIND(info)		ELF_ST_BIND(info)
+#define	ELF32_ST_TYPE(info)		ELF_ST_TYPE(info)
+#define	ELF32_ST_INFO(bind,type)	ELF_ST_INFO(bind,type)
+#define	ELF32_ST_VISIBILITY(other)	ELF_ST_VISIBILITY(other)
+
+#define	ELF64_ST_BIND(info)		ELF_ST_BIND(info)
+#define	ELF64_ST_TYPE(info)		ELF_ST_TYPE(info)
+#define	ELF64_ST_INFO(bind,type)	ELF_ST_INFO(bind,type)
+#define	ELF64_ST_VISIBILITY(other)	ELF_ST_VISIBILITY(other)
+
+typedef struct {
+	Elf32_Half	si_boundto;	/* direct bindings - symbol bound to */
+	Elf32_Half	si_flags;	/* per symbol flags */
+} Elf32_Syminfo;
+
+typedef struct {
+	Elf64_Half	si_boundto;	/* direct bindings - symbol bound to */
+	Elf64_Half	si_flags;	/* per symbol flags */
+} Elf64_Syminfo;
+
+#define	SYMINFO_FLG_DIRECT	0x0001	/* symbol ref has direct association
+					   to object containing definition */
+#define	SYMINFO_FLG_PASSTHRU	0x0002	/* ignored - see SYMINFO_FLG_FILTER */
+#define	SYMINFO_FLG_COPY	0x0004	/* symbol is a copy-reloc */
+#define	SYMINFO_FLG_LAZYLOAD	0x0008	/* object containing defn should be
+					   lazily-loaded */
+#define	SYMINFO_FLG_DIRECTBIND	0x0010	/* ref should be bound directly to
+					   object containing definition */
+#define	SYMINFO_FLG_NOEXTDIRECT	0x0020	/* don't let an external reference
+					   directly bind to this symbol */
+#define	SYMINFO_FLG_FILTER	0x0002	/* symbol ref is associated to a */
+#define	SYMINFO_FLG_AUXILIARY	0x0040	/*      standard or auxiliary filter */
+
+#define	SYMINFO_BT_SELF		0xffff	/* symbol bound to self */
+#define	SYMINFO_BT_PARENT	0xfffe	/* symbol bound to parent */
+#define	SYMINFO_BT_NONE		0xfffd	/* no special symbol binding */
+#define	SYMINFO_BT_EXTERN	0xfffc	/* symbol defined as external */
+#define	SYMINFO_BT_LOWRESERVE	0xff00	/* beginning of reserved entries */
+
+#define	SYMINFO_NONE		0	/* Syminfo version */
+#define	SYMINFO_CURRENT		1
+#define	SYMINFO_NUM		2
+
+/*
+ * These constants are used for Elf32_Verdef struct's version number.  
+ */
+#define VER_DEF_NONE		0
+#define	VER_DEF_CURRENT		1
+
+/*
+ * These constants are used for Elf32_Verdef struct's vd_flags.  
+ */
+#define VER_FLG_BASE		0x1
+#define	VER_FLG_WEAK		0x2
+
+/*
+ * These are used in an Elf32_Versym field.
+ */
+#define	VER_NDX_LOCAL		0
+#define	VER_NDX_GLOBAL		1
+
+/*
+ * These constants are used for Elf32_Verneed struct's version number.  
+ */
+#define	VER_NEED_NONE		0
+#define	VER_NEED_CURRENT	1
+
+/*
+ * GNU Extension hidding symb
+ */
+#define	VERSYM_HIDDEN		0x8000
+#define	VERSYM_VERSION		0x7fff
+
+#define	ELF_VER_CHR		'@'
+
+/*
+ * These are current size independent.
+ */
+
+typedef struct {
+	Elf32_Half	vd_version;	/* version number of structure */
+	Elf32_Half	vd_flags;	/* flags (VER_FLG_*) */
+	Elf32_Half	vd_ndx;		/* version index */
+	Elf32_Half	vd_cnt;		/* number of verdaux entries */
+	Elf32_Word	vd_hash;	/* hash of name */
+	Elf32_Word	vd_aux;		/* offset to verdaux entries */
+	Elf32_Word	vd_next;	/* offset to next verdef */
+} Elf32_Verdef;
+typedef	Elf32_Verdef	Elf64_Verdef;
+
+typedef struct {
+	Elf32_Word	vda_name;	/* string table offset of name */
+	Elf32_Word	vda_next;	/* offset to verdaux */
+} Elf32_Verdaux;
+typedef	Elf32_Verdaux	Elf64_Verdaux;
+
+typedef struct {
+	Elf32_Half	vn_version;	/* version number of structure */
+	Elf32_Half	vn_cnt;		/* number of vernaux entries */
+	Elf32_Word	vn_file;	/* string table offset of library name*/
+	Elf32_Word	vn_aux;		/* offset to vernaux entries */
+	Elf32_Word	vn_next;	/* offset to next verneed */
+} Elf32_Verneed;
+typedef	Elf32_Verneed	Elf64_Verneed;
+
+typedef struct {
+	Elf32_Word	vna_hash;	/* Hash of dependency name */
+	Elf32_Half	vna_flags;	/* flags (VER_FLG_*) */
+	Elf32_Half	vna_other;	/* unused */
+	Elf32_Word	vna_name;	/* string table offset to version name*/
+	Elf32_Word	vna_next;	/* offset to next vernaux */
+} Elf32_Vernaux;
+typedef	Elf32_Vernaux	Elf64_Vernaux;
+
+typedef struct {
+	Elf32_Half	vs_vers;
+} Elf32_Versym;
+typedef	Elf32_Versym	Elf64_Versym;
+
+#ifdef _KERNEL
+
+#define ELF_AUX_ENTRIES	14	/* Max size of aux array passed to loader */
+#define ELF32_NO_ADDR	(~(Elf32_Addr)0) /* Indicates addr. not yet filled in */
+#define ELF32_LINK_ADDR	((Elf32_Addr)-2) /* advises to use link address */
+#define ELF64_NO_ADDR	(~(Elf64_Addr)0) /* Indicates addr. not yet filled in */
+#define ELF64_LINK_ADDR	((Elf64_Addr)-2) /* advises to use link address */
+
+#if defined(ELFSIZE) && (ELFSIZE == 64)
+#define ELF_NO_ADDR	ELF64_NO_ADDR
+#define ELF_LINK_ADDR	ELF64_LINK_ADDR
+#elif defined(ELFSIZE) && (ELFSIZE == 32)
+#define ELF_NO_ADDR	ELF32_NO_ADDR
+#define ELF_LINK_ADDR	ELF32_LINK_ADDR
+#endif
+
+#ifndef ELF32_EHDR_FLAGS_OK
+#define	ELF32_EHDR_FLAGS_OK(eh)	1
+#endif
+
+#ifndef ELF64_EHDR_FLAGS_OK
+#define	ELF64_EHDR_FLAGS_OK(eh)	1
+#endif
+
+#if defined(ELFSIZE) && (ELFSIZE == 64)
+#define	ELF_EHDR_FLAGS_OK(eh)	ELF64_EHDR_FLAGS_OK(eh)
+#else
+#define	ELF_EHDR_FLAGS_OK(eh)	ELF32_EHDR_FLAGS_OK(eh)
+#endif
+
+#if defined(ELFSIZE)
+struct elf_args {
+        Elf_Addr  arg_entry;      /* program entry point */
+        Elf_Addr  arg_interp;     /* Interpreter load address */
+        Elf_Addr  arg_phaddr;     /* program header address */
+        Elf_Addr  arg_phentsize;  /* Size of program header */
+        Elf_Addr  arg_phnum;      /* Number of program headers */
+};
+#endif
+
+#ifdef _KERNEL_OPT
+#include "opt_execfmt.h"
+#endif
+
+#ifdef EXEC_ELF32
+int	exec_elf32_makecmds(struct lwp *, struct exec_package *);
+int	elf32_copyargs(struct lwp *, struct exec_package *,
+    	    struct ps_strings *, char **, void *);
+
+int	coredump_elf32(struct lwp *, void *);
+int	coredump_writenote_elf32(struct proc *, void *, Elf32_Nhdr *,
+	    const char *, void *);
+
+int	elf32_check_header(Elf32_Ehdr *, int);
+#endif
+
+#ifdef EXEC_ELF64
+int	exec_elf64_makecmds(struct lwp *, struct exec_package *);
+int	elf64_copyargs(struct lwp *, struct exec_package *,
+	    struct ps_strings *, char **, void *);
+
+int	coredump_elf64(struct lwp *, void *);
+int	coredump_writenote_elf64(struct proc *, void *, Elf64_Nhdr *,
+	    const char *, void *);
+
+int	elf64_check_header(Elf64_Ehdr *, int);
+#endif
+
+#endif /* _KERNEL */
+
+#endif /* !_SYS_EXEC_ELF_H_ */
diff --git a/cpukit/libdl/preinstall.am b/cpukit/libdl/preinstall.am
new file mode 100644
index 0000000..dba6cc4
--- /dev/null
+++ b/cpukit/libdl/preinstall.am
@@ -0,0 +1,7 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+	$(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
diff --git a/cpukit/libdl/rap-shell.c b/cpukit/libdl/rap-shell.c
new file mode 100644
index 0000000..664f3a3
--- /dev/null
+++ b/cpukit/libdl/rap-shell.c
@@ -0,0 +1,106 @@
+/*
+ *  COPYRIGHT (c) 2013 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtld
+ *
+ * @brief RTEMS Application Loader.
+ *
+ * Shell command wrappers for the RTEMS Application loader.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <rtems/rtl/rap.h>
+#include <rtems/rtl/rap-shell.h>
+
+static void
+shell_rap_command_help (void)
+{
+  printf ("usage: rap [cmd] [arg]\n" \
+          "Commands and options:\n" \
+          "ls:   List the loaded applications (also list)\n" \
+          "ld:   Load an application (also load)\n" \
+          "un:   Unload an application (also unload)\n");
+}
+
+static void
+shell_rap_get_error (const char* what)
+{
+  char message[64];
+  int  error;
+  error = rtems_rap_get_error (message, sizeof (message));
+  printf ("error: %s: (%d) %s\n", what, error, message);
+}
+
+static bool
+shell_rap_list_handler (void* handle)
+{
+  printf (" %-10p %-10p %-s\n",
+          handle, rtems_rap_dl_handle (handle), rtems_rap_name (handle));
+  return true;
+}
+
+static int
+shell_rap_list (int argc, char* argv[])
+{
+  printf (" App        DL Handle  Name\n");
+  return rtems_rap_iterate (shell_rap_list_handler) ? 0 : 1;
+}
+
+static int
+shell_rap_load (int argc, char* argv[])
+{
+  int r = 0;
+  if (argc == 0)
+  {
+    printf ("error: no application name\n");
+    return 0;
+  }
+  if (rtems_rap_load (argv[0], 0, argc - 1, (const char**) (argv + 1)))
+    printf ("%s loaded\n", argv[0]);
+  else
+  {
+    r = 1;
+    shell_rap_get_error ("loading");
+  }
+  return r;
+}
+
+int
+shell_rap (int argc, char* argv[])
+{
+  if (argc == 1)
+  {
+    shell_rap_command_help ();
+    return 0;
+  }
+
+  if ((strcmp (argv[1], "ls") == 0) ||
+      (strcmp (argv[1], "list") == 0))
+  {
+    return shell_rap_list (argc - 2, argv + 2);
+  }
+  else if ((strcmp (argv[1], "ld") == 0) ||
+           (strcmp (argv[1], "load") == 0))
+  {
+    return shell_rap_load (argc - 2, argv + 2);
+  }
+
+  printf ("error: invalid command: %s\n", argv[1]);
+  return 0;
+}
+
diff --git a/cpukit/libdl/rap-shell.h b/cpukit/libdl/rap-shell.h
new file mode 100644
index 0000000..c32529d
--- /dev/null
+++ b/cpukit/libdl/rap-shell.h
@@ -0,0 +1,14 @@
+/*
+ *  COPYRIGHT (c) 2013 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+
+#if !defined(_RAP_SHELL_H_)
+#define _RAP_SHELL_H_
+
+int shell_rap (int argc, char* argv[]);
+
+#endif
diff --git a/cpukit/libdl/rap.c b/cpukit/libdl/rap.c
new file mode 100644
index 0000000..8dec41e
--- /dev/null
+++ b/cpukit/libdl/rap.c
@@ -0,0 +1,484 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rap
+ *
+ * @brief RTEMS Application Loader
+ *
+ * This is the RAP implementation.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <rtems/libio_.h>
+
+#include <dlfcn.h>
+#include <rtems/rtl/rap.h>
+#include <rtems/rtl/rtl.h>
+
+#include "rtl-find-file.h"
+
+/**
+ * The global RAP data. This structure is allocated on the heap when the first
+ * call to location an application and is never released.
+ */
+typedef struct rtems_rap_data_s
+{
+  rtems_id            lock;           /**< The RAP lock id */
+  rtems_chain_control apps;           /**< List if loaded application. */
+  int                 last_errno;     /**< Last error number. */
+  char                last_error[64]; /**< Last error string. */
+} rtems_rap_data_t;
+
+/**
+ * The RAP file data. This structure is allocated on the heap when a file is
+ * loaded.
+ */
+typedef struct rtems_rap_app_s
+{
+  rtems_chain_node node;         /**< The node's link in the chain. */
+  const char*      name;         /**< The file name */
+  void*            handle;       /**< The dlopen handle. */
+} rtems_rap_app_t;
+
+/**
+ * Semaphore configuration to create a mutex.
+ */
+#define RTEMS_MUTEX_ATTRIBS \
+  (RTEMS_PRIORITY | RTEMS_BINARY_SEMAPHORE | \
+   RTEMS_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL)
+
+/**
+ * RTL entry.
+ */
+#if (RTL_GLUE(__USER_LABEL_PREFIX__, 1) == RTL_GLUE(_, 1))
+  #define RTL_ENTRY_POINT "_rtems"
+#else
+  #define RTL_ENTRY_POINT "rtems"
+#endif
+
+/**
+ * Static RAP data is returned to the user when the loader is locked.
+ */
+static rtems_rap_data_t rap_;
+
+/**
+ * Verbose level for the RAP loader.
+ */
+static bool rap_verbose;
+
+/**
+ * RAP entry call signature.
+ */
+typedef int (*rtems_rap_entry_t)(int argc, const char* argv[]);
+
+/**
+ * Forward decl.
+ */
+static bool rtems_rap_unlock (void);
+
+static bool
+rtems_rap_data_init (void)
+{
+  /*
+   * Lock the RAP. We only create a lock if a call is made. First we test if a
+   * lock is present. If one is present we lock it. If not the libio lock is
+   * locked and we then test the lock again. If not present we create the lock
+   * then release libio lock.
+   */
+  if (!rap_.lock)
+  {
+    rtems_libio_lock ();
+
+    if (!rap_.lock)
+    {
+      rtems_status_code sc;
+      rtems_id          lock;
+
+      /*
+       * Create the RAP lock.
+       */
+      sc = rtems_semaphore_create (rtems_build_name ('R', 'A', 'P', '_'),
+                                   1, RTEMS_MUTEX_ATTRIBS,
+                                   RTEMS_NO_PRIORITY, &lock);
+      if (sc != RTEMS_SUCCESSFUL)
+        return false;
+
+      sc = rtems_semaphore_obtain (lock, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+      if (sc != RTEMS_SUCCESSFUL)
+      {
+        rtems_semaphore_delete (lock);
+        return false;
+      }
+
+      rap_.lock = lock;
+
+      /*
+       * Initialise the objects list and create any required services.
+       */
+      rtems_chain_initialize_empty (&rap_.apps);
+    }
+
+    rtems_libio_unlock ();
+
+    rtems_rap_unlock ();
+  }
+  return true;
+}
+
+static rtems_rap_data_t*
+rtems_rap_lock (void)
+{
+  rtems_status_code sc;
+
+  if (!rtems_rap_data_init ())
+    return NULL;
+
+  sc = rtems_semaphore_obtain (rap_.lock,
+                               RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+  if (sc != RTEMS_SUCCESSFUL)
+  {
+    errno = EINVAL;
+    return NULL;
+  }
+
+  return &rap_;
+}
+
+static bool
+rtems_rap_unlock (void)
+{
+  /*
+   * Not sure any error should be returned or an assert.
+   */
+  rtems_status_code sc;
+  sc = rtems_semaphore_release (rap_.lock);
+  if ((sc != RTEMS_SUCCESSFUL) && (errno == 0))
+  {
+    errno = EINVAL;
+    return false;
+  }
+  return true;
+}
+
+static rtems_rap_app_t*
+rtems_rap_check_handle (void* handle)
+{
+  rtems_rap_app_t*  app;
+  rtems_chain_node* node;
+
+  app = handle;
+  node = rtems_chain_first (&rap_.apps);
+
+  while (!rtems_chain_is_tail (&rap_.apps, node))
+  {
+    rtems_rap_app_t* check = (rtems_rap_app_t*) node;
+    if (check == app)
+      return app;
+    node = rtems_chain_next (node);
+  }
+
+  return NULL;
+}
+
+static rtems_rap_app_t*
+rtems_rap_app_alloc (void)
+{
+  rtems_rap_app_t* app = malloc (sizeof (rtems_rap_app_t));
+  memset (app, 0, sizeof (rtems_rap_app_t));
+  rtems_chain_append (&rap_.apps, &app->node);
+  return app;
+}
+
+static void
+rtems_rap_app_free (rtems_rap_app_t* app)
+{
+  if (app->handle)
+  {
+    dlclose (app->handle);
+    app->handle = NULL;
+  }
+
+  if (!rtems_chain_is_node_off_chain (&app->node))
+    rtems_chain_extract (&app->node);
+}
+
+static bool
+rtems_rap_match_name (rtems_rap_app_t* app, const char* name)
+{
+  const char* a;
+
+  /*
+   * Assume the app name is absolute, ie points to the file on disk. This means
+   * there is at least one delimiter in the name.
+   */
+
+  if (strncmp (app->name, name, strlen (name)) == 0)
+    return true;
+
+  a = app->name + strlen (app->name) - 1;
+
+  while (a >= app->name)
+  {
+    if (rtems_filesystem_is_delimiter (*a))
+    {
+      const char* n = name;
+
+      ++a;
+
+      while (*a && *n)
+      {
+        if (*a == '.')
+        {
+          if (*n == '\0')
+            return true;
+        }
+
+        ++a;
+        ++n;
+      }
+
+      return false;
+    }
+
+    --a;
+  }
+
+  return false;
+}
+
+static void
+rtems_rap_get_rtl_error (void)
+{
+  rap_.last_errno =
+    rtems_rtl_get_error (rap_.last_error, sizeof (rap_.last_error));
+}
+
+static void
+rtems_rap_set_error (int error, const char* format, ...)
+{
+  rtems_rap_data_t* rap = rtems_rap_lock ();
+  va_list           ap;
+  va_start (ap, format);
+  rap->last_errno = error;
+  vsnprintf (rap->last_error, sizeof (rap->last_error), format, ap);
+  rtems_rap_unlock ();
+  va_end (ap);
+}
+
+bool
+rtems_rap_load (const char* name, int mode, int argc, const char* argv[])
+{
+  rtems_rap_data_t* rap = rtems_rap_lock ();
+
+  if (!rap)
+    return false;
+
+  if (rap_verbose)
+    printf ("rap: loading '%s'\n", name);
+
+  /*
+   * See if the app has already been loaded.
+   */
+  if (!rtems_rap_find (name))
+  {
+    rtems_rap_app_t*  app;
+    rtems_rap_entry_t init;
+    rtems_rap_entry_t fini;
+    size_t            size = 0;
+    int               r;
+
+    /*
+     * Allocate a new application descriptor and attempt to load it.
+     */
+    app = rtems_rap_app_alloc ();
+    if (app == NULL)
+    {
+      rtems_rap_set_error (ENOMEM, "no memory for application");
+      rtems_rap_unlock ();
+      return false;
+    }
+
+    /*
+     * Find the file in the file system using the search path.
+     */
+    if (!rtems_rtl_find_file (name, getenv ("PATH"), &app->name, &size))
+    {
+      rtems_rap_set_error (ENOENT, "file not found");
+      rtems_rap_app_free (app);
+      rtems_rap_unlock ();
+      return false;
+    }
+
+    app->handle = dlopen (app->name, RTLD_NOW | mode);
+    if (!app->handle)
+    {
+      rtems_rap_get_rtl_error ();
+      rtems_rap_app_free (app);
+      rtems_rap_unlock ();
+      return false;
+    }
+
+    init = dlsym (app->handle, RTL_ENTRY_POINT);
+    if (!init)
+    {
+      rtems_rap_get_rtl_error ();
+      rtems_rap_app_free (app);
+      rtems_rap_unlock ();
+      return false;
+    }
+
+    fini = dlsym (app->handle, RTL_ENTRY_POINT);
+    if (!fini)
+    {
+      rtems_rap_get_rtl_error ();
+      rtems_rap_app_free (app);
+      rtems_rap_unlock ();
+      return false;
+    }
+
+    r = init (argc, argv);
+    if (r != 0)
+    {
+      rtems_rap_set_error (r, "init call failure");
+      rtems_rap_app_free (app);
+      rtems_rap_unlock ();
+      return false;
+    }
+  }
+
+  rtems_rap_unlock ();
+
+  return true;
+}
+
+bool
+rtems_rap_unload (const char* name)
+{
+  rtems_rap_app_t*  app;
+  rtems_rap_entry_t fini;
+  int               r;
+
+  rtems_rap_lock ();
+
+  app = rtems_rap_find (name);
+
+  if (rap_verbose)
+    printf ("rap: unloading '%s'\n", name);
+
+  if (!app)
+  {
+    rtems_rap_set_error (ENOENT, "invalid handle");
+    rtems_rap_unlock ();
+    return false;
+  }
+
+  fini = dlsym (app->handle, RTL_ENTRY_POINT);
+  if (!fini)
+  {
+    rtems_rap_get_rtl_error ();
+    rtems_rap_unlock ();
+    return false;
+  }
+
+  r = fini (0, NULL);
+  if (r != 0)
+  {
+    rtems_rap_set_error (r, "fini failure");
+    rtems_rap_unlock ();
+    return false;
+  }
+
+  rtems_rap_app_free (app);
+  rtems_rap_unlock ();
+
+  return true;
+}
+
+void*
+rtems_rap_find (const char* name)
+{
+  rtems_rap_data_t* rap = rtems_rap_lock ();
+  rtems_chain_node* node;
+
+  node = rtems_chain_first (&rap->apps);
+
+  while (!rtems_chain_is_tail (&rap->apps, node))
+  {
+    rtems_rap_app_t* app = (rtems_rap_app_t*) node;
+    if (rtems_rap_match_name (app, name))
+    {
+      rtems_rap_unlock ();
+      return app;
+    }
+    node = rtems_chain_next (node);
+  }
+
+  rtems_rap_unlock ();
+
+  return NULL;
+}
+
+bool
+rtems_rap_iterate (rtems_rap_iterator_t iterator)
+{
+  rtems_rap_data_t* rap = rtems_rap_lock ();
+  rtems_chain_node* node;
+  bool              result = true;
+
+  node = rtems_chain_first (&rap->apps);
+
+  while (!rtems_chain_is_tail (&rap->apps, node))
+  {
+    rtems_rap_app_t* app = (rtems_rap_app_t*) node;
+    result = iterator (app);
+    if (!result)
+      break;
+    node = rtems_chain_next (node);
+  }
+
+  rtems_rap_unlock ();
+
+  return result;
+}
+
+const char*
+rtems_rap_name (void* handle)
+{
+  rtems_rap_app_t* app = rtems_rap_check_handle (handle);
+  if (app)
+    return app->name;
+  return NULL;
+}
+
+void*
+rtems_rap_dl_handle (void* handle)
+{
+  rtems_rap_app_t* app = rtems_rap_check_handle (handle);
+  if (app)
+    return app->handle;
+  return NULL;
+}
+
+int
+rtems_rap_get_error (char* message, size_t max_message)
+{
+  rtems_rap_data_t* rap = rtems_rap_lock ();
+  int               last_errno = rap->last_errno;
+  strncpy (message, rap->last_error, sizeof (rap->last_error));
+  rtems_rap_unlock ();
+  return last_errno;
+}
diff --git a/cpukit/libdl/rap.h b/cpukit/libdl/rap.h
new file mode 100644
index 0000000..e53699f
--- /dev/null
+++ b/cpukit/libdl/rap.h
@@ -0,0 +1,115 @@
+/*
+ *  COPYRIGHT (c) 2013 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rap
+ *
+ * @brief RTEMS Application Loader
+ *
+ * This is the RTEMS Application loader for files in the RAP format.
+ */
+
+#if !defined (_RAP_H_)
+#define _RAP_H_
+
+#include <rtems.h>
+#include <rtems/chain.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup rtems_rap RTEMS Application Loader
+ *
+ * The module implements an application loader for files in the RAP format. The
+ * RAP format is:
+ *
+ *   <header>
+ *   <compressed container>
+ *
+ * The compressed container is a stream of ELF relocatable object files.
+ *
+ *  TBD.
+ */
+
+/**
+ * The module iterator handle.
+ */
+typedef bool (*rtems_rap_iterator_t) (void* handle);
+
+/**
+ * Load an application.
+ *
+ * @param name The name of the application file.
+ * @return bool True if the module loads else an error.
+ */
+bool rtems_rap_load (const char* name, int mode, int argc, const char* argv[]);
+
+/**
+ * Unload an application.
+ *
+ * @param obj The application descriptor.
+ * @retval true The application file has been unloaded.
+ * @retval false The application could not be unloaded.
+ */
+bool rtems_rap_unload (const char* name);
+
+/**
+ * Find the application handle given a file name.
+ *
+ * @param name The name of the application file. It can be absolute or
+ *             relative. Relative names can the basename with an extension.
+ * @retval NULL No application file with that name found.
+ * @return void* The application descriptor.
+ */
+void* rtems_rap_find (const char* name);
+
+/**
+ * Run an iterator over the modules calling the iterator function.
+ *
+ * @param iterator The iterator function.
+ * @retval true The iterator function returned did not return false.
+ * @retval false The iterator function returned false..
+ */
+bool rtems_rap_iterate (rtems_rap_iterator_t iterator);
+
+/**
+ * Return the name of the module given a handle.
+ *
+ * @param handle The module handle.
+ * @return const char* The name of the module if the handle is valid else it
+ *                     is NULL.
+ */
+const char* rtems_rap_name (void* handle);
+
+/**
+ * Return the DL handle used to load the module given the RAP handle.
+ *
+ * @param handle The module handle.
+ * @return void* The DL handle returned by the dlopen call.
+ */
+void* rtems_rap_dl_handle (void* handle);
+
+/**
+ * Get the last error message clearing it. This call is not thread safe is
+ * multiple threads are loading object files at the same time. This call
+ * follows the model provided by the dlopen family of calls.
+ *
+ * @param message Pointer to a buffer to copy the message into.
+ * @param max_message The maximum message that can be copied.
+ * @return int The last error number.
+ */
+int rtems_rap_get_error (char* message, size_t max_message);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/libdl/rtl-alloc-heap.c b/cpukit/libdl/rtl-alloc-heap.c
new file mode 100644
index 0000000..44a4816
--- /dev/null
+++ b/cpukit/libdl/rtl-alloc-heap.c
@@ -0,0 +1,33 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Allocator for the standard heap.
+ */
+
+#include <stdlib.h>
+
+#include "rtl-alloc-heap.h"
+
+void
+rtems_rtl_alloc_heap (bool                  allocate,
+                      rtems_rtl_alloc_tag_t tag,
+                      void**                address,
+                      size_t                size)
+{
+  if (allocate)
+    *address = malloc (size);
+  else
+  {
+    free (*address);
+    *address = NULL;
+  }
+}
diff --git a/cpukit/libdl/rtl-alloc-heap.h b/cpukit/libdl/rtl-alloc-heap.h
new file mode 100644
index 0000000..d927655
--- /dev/null
+++ b/cpukit/libdl/rtl-alloc-heap.h
@@ -0,0 +1,47 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Allocator for the standard heap.
+ */
+
+#if !defined (_RTEMS_RTL_ALLOC_HEAP_H_)
+#define _RTEMS_RTL_ALLOC_HEAP_H_
+
+#include <rtems/rtl/rtl-allocator.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Allocator handler for the standard libc heap.
+ *
+ * @param allocation If true the request is to allocate memory else free.
+ * @param tag The type of allocation request.
+ * @param address Pointer to the memory address. If an allocation the value is
+ *                unspecific on entry and the allocated address or NULL on
+ *                exit. The NULL value means the allocation failed. If a delete
+ *                or free request the memory address is the block to free. A
+ *                free request of NULL is silently ignored.
+ * @param size The size of the allocation if an allocation request and
+ *             not used if deleting or freeing a previous allocation.
+ */
+void rtems_rtl_alloc_heap(bool                  allocate,
+                          rtems_rtl_alloc_tag_t tag,
+                          void**                address,
+                          size_t                size);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/libdl/rtl-allocator.c b/cpukit/libdl/rtl-allocator.c
new file mode 100644
index 0000000..b845013
--- /dev/null
+++ b/cpukit/libdl/rtl-allocator.c
@@ -0,0 +1,210 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Allocator
+ */
+
+#include <stdio.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-alloc-heap.h"
+#include "rtl-trace.h"
+
+/**
+ * Tags as symbols for tracing.
+ */
+#if RTEMS_RTL_TRACE
+static const char* tag_labels[6] =
+{
+  "OBJECT",
+  "SYMBOL",
+  "EXTERNAL",
+  "READ",
+  "READ_WRITE",
+  "READ_EXEC",
+};
+#define rtems_rtl_trace_tag_label(_l) tag_labels[_l]
+#else
+#define rtems_rtl_trace_tag_label(_l) ""
+#endif
+
+void
+rtems_rtl_alloc_initialise (rtems_rtl_alloc_data_t* data)
+{
+  int c;
+  data->allocator = rtems_rtl_alloc_heap;
+  for (c = 0; c < RTEMS_RTL_ALLOC_TAGS; ++c)
+    rtems_chain_initialize_empty (&data->indirects[c]);
+}
+
+void*
+rtems_rtl_alloc_new (rtems_rtl_alloc_tag_t tag, size_t size, bool zero)
+{
+  rtems_rtl_data_t* rtl = rtems_rtl_lock ();
+  void*             address = NULL;
+
+  if (rtl)
+    rtl->allocator.allocator (true, tag, &address, size);
+
+  rtems_rtl_unlock ();
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
+    printf ("rtl: alloc: new: %s addr=%p size=%zu\n",
+            rtems_rtl_trace_tag_label (tag), address, size);
+
+  if (zero)
+    memset (address, 0, size);
+
+  return address;
+}
+
+void
+rtems_rtl_alloc_del (rtems_rtl_alloc_tag_t tag, void* address)
+{
+  rtems_rtl_data_t* rtl = rtems_rtl_lock ();
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
+    printf ("rtl: alloc: del: %s addr=%p\n",
+            rtems_rtl_trace_tag_label (tag), address);
+
+  if (rtl && address)
+    rtl->allocator.allocator (false, tag, &address, 0);
+
+  rtems_rtl_unlock ();
+}
+
+rtems_rtl_allocator_t
+rtems_rtl_alloc_hook (rtems_rtl_allocator_t handler)
+{
+  rtems_rtl_data_t* rtl = rtems_rtl_lock ();
+  rtems_rtl_allocator_t previous = rtl->allocator.allocator;
+  rtl->allocator.allocator = handler;
+  rtems_rtl_unlock ();
+  return previous;
+}
+
+void
+rtems_rtl_alloc_indirect_new (rtems_rtl_alloc_tag_t tag,
+                              rtems_rtl_ptr_t*      handle,
+                              size_t                size)
+{
+  rtems_rtl_data_t* rtl = rtems_rtl_lock ();
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
+  {
+    if (!rtems_rtl_ptr_null (handle))
+      printf ("rtl: alloc: inew: %s handle=%p: not null\n",
+              rtems_rtl_trace_tag_label (tag), handle);
+    printf ("rtl: alloc: inew: %s handle=%p size=%zd\n",
+            rtems_rtl_trace_tag_label (tag), handle, size);
+  }
+
+  if (rtl)
+  {
+    rtems_rtl_alloc_data_t* allocator = &rtl->allocator;
+    handle->pointer = rtems_rtl_alloc_new (tag, size, false);
+    if (!rtems_rtl_ptr_null (handle))
+      rtems_chain_append_unprotected (&allocator->indirects[tag],
+                                      &handle->node);
+  }
+
+  rtems_rtl_unlock ();
+}
+
+void
+rtems_rtl_alloc_indirect_del (rtems_rtl_alloc_tag_t tag,
+                              rtems_rtl_ptr_t*      handle)
+{
+  rtems_rtl_data_t* rtl = rtems_rtl_lock ();
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
+  {
+    if (rtems_rtl_ptr_null (handle))
+      printf ("rtl: alloc: idel: %s handle=%p: is null\n",
+              rtems_rtl_trace_tag_label (tag), handle);
+    printf ("rtl: alloc: idel: %s handle=%p\n",
+            rtems_rtl_trace_tag_label (tag), handle);
+  }
+
+  if (rtl && !rtems_rtl_ptr_null (handle))
+  {
+    rtems_chain_extract_unprotected (&handle->node);
+    rtems_rtl_alloc_del (tag, &handle->pointer);
+  }
+}
+
+bool
+rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
+                            void** const_base, size_t const_size,
+                            void** data_base, size_t data_size,
+                            void** bss_base, size_t bss_size)
+{
+  *text_base = *const_base = *data_base = *bss_base = NULL;
+
+  if (text_size)
+  {
+    *text_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ_EXEC,
+                                      text_size, false);
+    if (!*text_base)
+    {
+      return false;
+    }
+  }
+
+  if (const_size)
+  {
+    *const_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ,
+                                       const_size, false);
+    if (!*const_base)
+    {
+      rtems_rtl_alloc_module_del (text_base, const_base, data_base, bss_base);
+      return false;
+    }
+  }
+
+  if (data_size)
+  {
+    *data_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ_WRITE,
+                                      data_size, false);
+    if (!*data_base)
+    {
+      rtems_rtl_alloc_module_del (text_base, const_base, data_base, bss_base);
+      return false;
+    }
+  }
+
+  if (bss_size)
+  {
+    *bss_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ_WRITE,
+                                     bss_size, false);
+    if (!*bss_base)
+    {
+      rtems_rtl_alloc_module_del (text_base, const_base, data_base, bss_base);
+      return false;
+    }
+  }
+
+  return true;
+}
+
+void
+rtems_rtl_alloc_module_del (void** text_base,
+                            void** const_base,
+                            void** data_base,
+                            void** bss_base)
+{
+  rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_WRITE, *bss_base);
+  rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_WRITE, *data_base);
+  rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ, *const_base);
+  rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_EXEC, *text_base);
+  *text_base = *const_base = *data_base = *bss_base = NULL;
+}
diff --git a/cpukit/libdl/rtl-allocator.h b/cpukit/libdl/rtl-allocator.h
new file mode 100644
index 0000000..8e90b7b
--- /dev/null
+++ b/cpukit/libdl/rtl-allocator.h
@@ -0,0 +1,176 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Allocator
+ */
+
+#if !defined (_RTEMS_RTL_ALLOCATOR_H_)
+#define _RTEMS_RTL_ALLOCATOR_H_
+
+#include <stdbool.h>
+
+#include "rtl-indirect-ptr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Define the types of allocation the loader requires.
+ *
+ * @note It is best to use the object tag for general memory allocation and to
+ *       leave the tags with specific access properties to the module data
+ */
+enum rtems_rtl_alloc_tags_e {
+  RTEMS_RTL_ALLOC_OBJECT,     /**< A generic memory object. */
+  RTEMS_RTL_ALLOC_SYMBOL,     /**< Memory used for symbols. */
+  RTEMS_RTL_ALLOC_EXTERNAL,   /**< Memory used for external symbols. */
+  RTEMS_RTL_ALLOC_READ,       /**< The memory is read only. */
+  RTEMS_RTL_ALLOC_READ_WRITE, /**< The memory is read and write. */
+  RTEMS_RTL_ALLOC_READ_EXEC   /**< The memory is read and executable. */
+};
+
+/**
+ * The allocator tag type.
+ */
+typedef enum rtems_rtl_alloc_tags_e rtems_rtl_alloc_tag_t;
+
+/**
+ * The number of tags.
+ */
+#define RTEMS_RTL_ALLOC_TAGS ((size_t) (RTEMS_RTL_ALLOC_READ_EXEC + 1))
+
+/**
+ * Allocator handler handles all RTL allocations. It can be hooked and
+ * overridded for customised allocation schemes or memory maps.
+ *
+ * @param allocation If true the request is to allocate memory else free.
+ * @param tag The type of allocation request.
+ * @param address Pointer to the memory address. If an allocation the value is
+ *                unspecific on entry and the allocated address or NULL on
+ *                exit. The NULL value means the allocation failed. If a delete
+ *                or free request the memory address is the block to free. A
+ *                free request of NULL is silently ignored.
+ * @param size The size of the allocation if an allocation request and
+ *             not used if deleting or freeing a previous allocation.
+ */
+typedef void (*rtems_rtl_allocator_t)(bool                  allocate,
+                                      rtems_rtl_alloc_tag_t tag,
+                                      void**                address,
+                                      size_t                size);
+
+/**
+ * The allocator data.
+ */
+struct rtems_rtl_alloc_data_s {
+  /**< The memory allocator handler. */
+  rtems_rtl_allocator_t allocator;
+  /**< The indirect pointer chains. */
+  rtems_chain_control indirects[RTEMS_RTL_ALLOC_TAGS];
+};
+
+typedef struct rtems_rtl_alloc_data_s rtems_rtl_alloc_data_t;
+
+/**
+ * Initialise the allocate data.
+ *
+ * @param data The data to initialise.
+ */
+void rtems_rtl_alloc_initialise (rtems_rtl_alloc_data_t* data);
+
+/**
+ * The Runtime Loader allocator new allocates new memory and optionally clear
+ * the memory if requested.
+ *
+ * @param tag The type of allocation request.
+ * @param size The size of the allocation.
+ * @param zero If true the memory is cleared.
+ * @return void* The memory address or NULL is not memory available.
+ */
+void* rtems_rtl_alloc_new (rtems_rtl_alloc_tag_t tag, size_t size, bool zero);
+
+/**
+ * The Runtime Loader allocator delete deletes allocated memory.
+ *
+ * @param tag The type of allocation request.
+ * @param address The memory address to delete. A NULL is ignored.
+ */
+void rtems_rtl_alloc_del (rtems_rtl_alloc_tag_t tag, void* address);
+
+/**
+ * Hook the Runtime Loader allocatior. A handler can call the previous handler
+ * in the chain to use it for specific tags. The default handler uses the
+ * system heap. Do not unhook your handler if memory it allocates has not been
+ * returned.
+ *
+ * @param handler The handler to use as the allocator.
+ * @return rtems_rtl_alloc_handler_t The previous handler.
+ */
+rtems_rtl_allocator_t rtems_rtl_alloc_hook (rtems_rtl_allocator_t handler);
+
+/**
+ * Allocate memory to an indirect handle.
+ *
+ * @param tag The type of allocation request.
+ * @param handle The handle to allocate the memory to.
+ * @param size The size of the allocation.
+ */
+void rtems_rtl_alloc_indirect_new (rtems_rtl_alloc_tag_t tag,
+                                   rtems_rtl_ptr_t*      handle,
+                                   size_t                size);
+
+/**
+ * Free memory from an indirect handle.
+ *
+ * @param tag The type of allocation request.
+ * @param handle The handle to free the memory from.
+ */
+void rtems_rtl_alloc_indirect_del (rtems_rtl_alloc_tag_t tag,
+                                   rtems_rtl_ptr_t*      handle);
+
+/**
+ * Allocate the memory for a module given the size of the text, const, data and
+ * bss sections. If any part of the allocation fails the no memory is
+ * allocated.
+ *
+ * @param text_base Pointer to the text base pointer.
+ * @param text_size The size of the read/exec section.
+ * @param const_base Pointer to the const base pointer.
+ * @param const_size The size of the read only section.
+ * @param data_base Pointer to the data base pointer.
+ * @prarm data_size The size of the read/write secton.
+ * @param bss_base Pointer to the bss base pointer.
+ * @param bss_size The size of the read/write.
+ * @retval true The memory has been allocated.
+ * @retval false The allocation of memory has failed.
+ */
+bool rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
+                                 void** const_base, size_t const_size,
+                                 void** data_base, size_t data_size,
+                                 void** bss_base, size_t bss_size);
+
+/**
+ * Free the memory allocated to a module.
+ *
+ * @param text_base Pointer to the text base pointer.
+ * @param const_base Pointer to the const base pointer.
+ * @param data_base Pointer to the data base pointer.
+ * @param bss_base Pointer to the bss base pointer.
+ */
+void rtems_rtl_alloc_module_del (void** text_base, void** const_base,
+                                 void** data_base, void** bss_base);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/libdl/rtl-chain-iterator.c b/cpukit/libdl/rtl-chain-iterator.c
new file mode 100644
index 0000000..39184ee
--- /dev/null
+++ b/cpukit/libdl/rtl-chain-iterator.c
@@ -0,0 +1,57 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtld
+ *
+ * @brief RTEMS Run-Time Link Editor Chain Iterator
+ *
+ * A means of executing an iterator on a chain.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "rtl-chain-iterator.h"
+
+bool
+rtems_rtl_chain_iterate (rtems_chain_control* chain,
+                         rtems_chain_iterator iterator,
+                         void*                data)
+{
+  rtems_chain_node* node = rtems_chain_first (chain);
+  while (!rtems_chain_is_tail (chain, node))
+  {
+    rtems_chain_node* next_node = rtems_chain_next (node);
+    if (!iterator (node, data))
+      return false;
+    node = next_node;
+  }
+  return true;
+}
+
+/**
+ * Count iterator.
+ */
+static bool
+rtems_rtl_count_iterator (rtems_chain_node* node, void* data)
+{
+  int* count = data;
+  ++(*count);
+  return true;
+}
+
+int
+rtems_rtl_chain_count (rtems_chain_control* chain)
+{
+  int count = 0;
+  rtems_rtl_chain_iterate (chain, rtems_rtl_count_iterator, &count);
+  return count;
+}
diff --git a/cpukit/libdl/rtl-chain-iterator.h b/cpukit/libdl/rtl-chain-iterator.h
new file mode 100644
index 0000000..b3781e0
--- /dev/null
+++ b/cpukit/libdl/rtl-chain-iterator.h
@@ -0,0 +1,59 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Chain Iterator.
+ */
+
+#if !defined (_RTEMS_RTL_CHAIN_ITERATOR_H_)
+#define _RTEMS_RTL_CHAIN_ITERATOR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <rtems/chain.h>
+
+/**
+ * Chain iterator handler.
+ */
+typedef bool (*rtems_chain_iterator) (rtems_chain_node* node, void* data);
+
+/**
+ * Iterate a chain of nodes invoking the iterator handler. Supply a data
+ * pointer the iterator moves data between the invoker and the iterator.
+ *
+ * The iterator allows removal of the node from the chain.
+ *
+ * @param chain The chain of nodes to iterator over.
+ * @param iterator The iterator handler called once for each node.
+ * @param data Pointer to the data used by the iterator.
+ * @retval true The whole chain was iterated over.
+ * @retval false The iterator returned false.
+ */
+bool
+rtems_rtl_chain_iterate (rtems_chain_control* chain,
+                         rtems_chain_iterator iterator,
+                         void*                data);
+
+/**
+ * Count the number of nodes on the chain.
+ *
+ * @param chain The chain to count the nodes of.
+ * @return int The number of nodes.
+ */
+int rtems_rtl_chain_count (rtems_chain_control* chain);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/libdl/rtl-debugger.c b/cpukit/libdl/rtl-debugger.c
new file mode 100644
index 0000000..2eff2bd
--- /dev/null
+++ b/cpukit/libdl/rtl-debugger.c
@@ -0,0 +1,96 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtl
+ *
+ * @brief RTEMS Module Loading Debugger Interface.
+ *
+ * Inspection of run-time linkers in NetBSD and Android show a common type of
+ * structure that is used to interface to GDB. The NetBSD definition of this
+ * interface is being used and is defined in <link.h>. It defines a protocol
+ * that is used by GDB to inspect the state of dynamic libraries. I have not
+ * checked GDB code at when writing this comment but I suspect GDB sets a break
+ * point on the r_brk field of _rtld_debug and it has code that detects this
+ * break point being hit. When this happens it reads the state and performs the
+ * operation based on the r_state field.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <link.h>
+#include <rtems/rtl/rtl.h>
+#include "rtl-trace.h"
+#include "rtl-obj-fwd.h"
+
+struct r_debug  _rtld_debug;
+
+void
+_rtld_debug_state (void)
+{
+  /*
+   * Empty. GDB only needs to hit this location.
+   */
+}
+
+int
+_rtld_linkmap_add (rtems_rtl_obj_t* obj)
+{
+  struct link_map* l = (struct link_map*)obj->detail;
+  struct link_map* prev;
+  uint32_t obj_num = obj->obj_num;
+  int i;
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
+    printf ("rtl: linkmap_add\n");
+
+  for (i = 0; i < obj_num; ++i)
+  {
+    l[i].sec_addr[rap_text] = obj->text_base;
+    l[i].sec_addr[rap_const] = obj->const_base;
+    l[i].sec_addr[rap_data] = obj->data_base;
+    l[i].sec_addr[rap_bss] = obj->bss_base;
+  }
+
+  if (_rtld_debug.r_map == NULL)
+  {
+    _rtld_debug.r_map = l;
+    return true;
+  }
+
+  for (prev = _rtld_debug.r_map; prev->l_next != NULL; prev = prev->l_next);
+
+  l->l_prev = prev;
+  prev->l_next = l;
+
+  return true;
+}
+
+void
+_rtld_linkmap_delete (rtems_rtl_obj_t* obj)
+{
+  struct link_map* l = (struct link_map*)obj->detail;
+  /* link_maps are allocated together if not 1 */
+  struct link_map* e = l + obj->obj_num - 1;
+
+  while (e && e->l_next) e = e->l_next;
+
+  if (l->l_prev == NULL)
+  {
+    if ((_rtld_debug.r_map = e->l_next) != NULL)
+      e->l_next->l_prev = NULL;
+    return;
+  }
+  if ((l->l_prev->l_next = e->l_next) != NULL)
+    e->l_next->l_prev = l->l_prev;
+  return;
+}
diff --git a/cpukit/libdl/rtl-elf.c b/cpukit/libdl/rtl-elf.c
new file mode 100644
index 0000000..e4f1ffc
--- /dev/null
+++ b/cpukit/libdl/rtl-elf.c
@@ -0,0 +1,882 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtld
+ *
+ * @brief RTEMS Run-Time Link Editor
+ *
+ * This is the RTL implementation.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-elf.h"
+#include "rtl-error.h"
+#include "rtl-trace.h"
+#include "rtl-unresolved.h"
+
+/**
+ * The offsets in the unresolved array.
+ */
+#define REL_R_OFFSET (0)
+#define REL_R_INFO   (1)
+#define REL_R_ADDEND (2)
+
+/**
+ * The ELF format signature.
+ */
+static rtems_rtl_loader_format_t elf_sig =
+{
+  .label = "ELF",
+  .flags = RTEMS_RTL_FMT_ELF
+};
+
+static bool
+rtems_rtl_elf_machine_check (Elf_Ehdr* ehdr)
+{
+  /*
+   * This code is determined by the NetBSD machine headers.
+   */
+  switch (ehdr->e_machine)
+  {
+    ELFDEFNNAME (MACHDEP_ID_CASES)
+    default:
+      return false;
+  }
+  return true;
+}
+
+bool
+rtems_rtl_elf_find_symbol (rtems_rtl_obj_t* obj,
+                           const Elf_Sym*   sym,
+                           const char*      symname,
+                           Elf_Word*        value)
+{
+  rtems_rtl_obj_sect_t* sect;
+
+  if (ELF_ST_TYPE(sym->st_info) == STT_NOTYPE)
+  {
+    rtems_rtl_obj_sym_t* symbol = rtems_rtl_symbol_global_find (symname);
+    if (!symbol)
+    {
+      rtems_rtl_set_error (EINVAL, "global symbol not found: %s", symname);
+      return false;
+    }
+
+    *value = (Elf_Word) symbol->value;
+    return true;
+  }
+
+  sect = rtems_rtl_obj_find_section_by_index (obj, sym->st_shndx);
+  if (!sect)
+  {
+    rtems_rtl_set_error (EINVAL, "reloc symbol's section not found");
+    return false;
+  }
+
+  *value = sym->st_value + (Elf_Word) sect->base;
+  return true;
+}
+
+static bool
+rtems_rtl_elf_relocator (rtems_rtl_obj_t*      obj,
+                         int                   fd,
+                         rtems_rtl_obj_sect_t* sect,
+                         void*                 data)
+{
+  rtems_rtl_obj_cache_t* symbols;
+  rtems_rtl_obj_cache_t* strings;
+  rtems_rtl_obj_cache_t* relocs;
+  rtems_rtl_obj_sect_t*  targetsect;
+  rtems_rtl_obj_sect_t*  symsect;
+  rtems_rtl_obj_sect_t*  strtab;
+  bool                   is_rela;
+  size_t                 reloc_size;
+  int                    reloc;
+
+  /*
+   * First check if the section the relocations are for exists. If it does not
+   * exist ignore these relocations. They are most probably debug sections.
+   */
+  targetsect = rtems_rtl_obj_find_section_by_index (obj, sect->info);
+  if (!targetsect)
+    return true;
+
+  rtems_rtl_obj_caches (&symbols, &strings, &relocs);
+
+  if (!symbols || !strings || !relocs)
+    return false;
+
+  symsect = rtems_rtl_obj_find_section (obj, ".symtab");
+  if (!symsect)
+  {
+    rtems_rtl_set_error (EINVAL, "no .symtab section");
+    return false;
+  }
+
+  strtab = rtems_rtl_obj_find_section (obj, ".strtab");
+  if (!strtab)
+  {
+    rtems_rtl_set_error (EINVAL, "no .strtab section");
+    return false;
+  }
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+    printf ("rtl: relocation: %s, syms:%s\n", sect->name, symsect->name);
+
+  /*
+   * Handle the different relocation record types.
+   */
+  is_rela = ((sect->flags & RTEMS_RTL_OBJ_SECT_RELA) ==
+             RTEMS_RTL_OBJ_SECT_RELA) ? true : false;
+  reloc_size = is_rela ? sizeof (Elf_Rela) : sizeof (Elf_Rel);
+
+  for (reloc = 0; reloc < (sect->size / reloc_size); ++reloc)
+  {
+    uint8_t         relbuf[reloc_size];
+    const Elf_Rela* rela = (const Elf_Rela*) relbuf;
+    const Elf_Rel*  rel = (const Elf_Rel*) relbuf;
+    Elf_Sym         sym;
+    const char*     symname = NULL;
+    off_t           off;
+    Elf_Word        type;
+    Elf_Word        symvalue = 0;
+    bool            relocate;
+
+    off = obj->ooffset + sect->offset + (reloc * reloc_size);
+
+    if (!rtems_rtl_obj_cache_read_byval (relocs, fd, off,
+                                         &relbuf[0], reloc_size))
+      return false;
+
+    if (is_rela)
+      off = (obj->ooffset + symsect->offset +
+             (ELF_R_SYM (rela->r_info) * sizeof (sym)));
+    else
+      off = (obj->ooffset + symsect->offset +
+             (ELF_R_SYM (rel->r_info) * sizeof (sym)));
+
+    if (!rtems_rtl_obj_cache_read_byval (symbols, fd, off,
+                                         &sym, sizeof (sym)))
+      return false;
+
+    /*
+     * Only need the name of the symbol if global.
+     */
+    if (ELF_ST_TYPE (sym.st_info) == STT_NOTYPE)
+    {
+      size_t len;
+      off = obj->ooffset + strtab->offset + sym.st_name;
+      len = RTEMS_RTL_ELF_STRING_MAX;
+
+      if (!rtems_rtl_obj_cache_read (strings, fd, off,
+                                     (void**) &symname, &len))
+        return false;
+    }
+
+    /*
+     * See if the record references an external symbol. If it does find the
+     * symbol value. If the symbol cannot be found flag the object file as
+     * having unresolved externals and store the externals. The load of an
+     * object after this one may provide the unresolved externals.
+     */
+    if (is_rela)
+      type = ELF_R_TYPE(rela->r_info);
+    else
+      type = ELF_R_TYPE(rel->r_info);
+
+    relocate = true;
+
+    if (rtems_rtl_elf_rel_resolve_sym (type))
+    {
+      if (!rtems_rtl_elf_find_symbol (obj, &sym, symname, &symvalue))
+      {
+        uint16_t         flags = 0;
+        rtems_rtl_word_t rel_words[3];
+
+        relocate = false;
+
+        if (is_rela)
+        {
+          flags = 1;
+          rel_words[REL_R_OFFSET] = rela->r_offset;
+          rel_words[REL_R_INFO] = rela->r_info;
+          rel_words[REL_R_ADDEND] = rela->r_addend;
+        }
+        else
+        {
+          rel_words[REL_R_OFFSET] = rel->r_offset;
+          rel_words[REL_R_INFO] = rel->r_info;
+          rel_words[REL_R_ADDEND] = 0;
+        }
+
+        if (!rtems_rtl_unresolved_add (obj,
+                                       flags,
+                                       symname,
+                                       targetsect->section,
+                                       rel_words))
+          return false;
+
+        ++obj->unresolved;
+      }
+    }
+
+    if (relocate)
+    {
+      if (is_rela)
+      {
+        if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+          printf ("rtl: rela: sym:%s(%-2d)=%08lx type:%-2d off:%08lx addend:%d\n",
+                  symname, (int) ELF_R_SYM (rela->r_info), symvalue,
+                  (int) ELF_R_TYPE (rela->r_info), rela->r_offset, (int) rela->r_addend);
+        if (!rtems_rtl_elf_relocate_rela (obj, rela, targetsect,
+                                          symname, sym.st_info, symvalue))
+          return false;
+      }
+      else
+      {
+        if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+          printf ("rtl: rel: sym:%s(%-2d)=%08lx type:%-2d off:%08lx\n",
+                  symname, (int) ELF_R_SYM (rel->r_info), symvalue,
+                  (int) ELF_R_TYPE (rel->r_info), rel->r_offset);
+        if (!rtems_rtl_elf_relocate_rel (obj, rel, targetsect,
+                                         symname, sym.st_info, symvalue))
+          return false;
+      }
+    }
+  }
+
+  /*
+   * Set the unresolved externals status if there are unresolved externals.
+   */
+  if (obj->unresolved)
+    obj->flags |= RTEMS_RTL_OBJ_UNRESOLVED;
+
+  return true;
+}
+
+bool
+rtems_rtl_obj_relocate_unresolved (rtems_rtl_unresolv_reloc_t* reloc,
+                                   rtems_rtl_obj_sym_t*        sym)
+{
+  rtems_rtl_obj_sect_t* sect;
+  bool                  is_rela;
+  Elf_Word              symvalue;
+
+  is_rela =reloc->flags & 1;
+
+  sect = rtems_rtl_obj_find_section_by_index (reloc->obj, reloc->sect);
+  if (!sect)
+  {
+    rtems_rtl_set_error (ENOEXEC, "unresolved sect not found");
+    return false;
+  }
+
+  symvalue = (Elf_Word) (intptr_t) sym->value;
+  if (is_rela)
+  {
+    Elf_Rela rela;
+    rela.r_offset = reloc->rel[REL_R_OFFSET];
+    rela.r_info = reloc->rel[REL_R_INFO];
+    rela.r_addend = reloc->rel[REL_R_ADDEND];
+    if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+          printf ("rtl: rela: sym:%-2d type:%-2d off:%08lx addend:%d\n",
+                  (int) ELF_R_SYM (rela.r_info), (int) ELF_R_TYPE (rela.r_info),
+                  rela.r_offset, (int) rela.r_addend);
+    if (!rtems_rtl_elf_relocate_rela (reloc->obj, &rela, sect,
+                                      sym->name, sym->data, symvalue))
+      return false;
+  }
+  else
+  {
+    Elf_Rel rel;
+    rel.r_offset = reloc->rel[REL_R_OFFSET];
+    rel.r_info = reloc->rel[REL_R_INFO];
+    if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+      printf ("rtl: rel: sym:%-2d type:%-2d off:%08lx\n",
+              (int) ELF_R_SYM (rel.r_info), (int) ELF_R_TYPE (rel.r_info),
+              rel.r_offset);
+    if (!rtems_rtl_elf_relocate_rel (reloc->obj, &rel, sect,
+                                     sym->name, sym->data, symvalue))
+      return false;
+  }
+
+  if (reloc->obj->unresolved)
+  {
+    --reloc->obj->unresolved;
+    if (!reloc->obj->unresolved)
+      reloc->obj->flags &= ~RTEMS_RTL_OBJ_UNRESOLVED;
+  }
+
+  return true;
+}
+
+static bool
+rtems_rtl_elf_symbols (rtems_rtl_obj_t*      obj,
+                       int                   fd,
+                       rtems_rtl_obj_sect_t* sect,
+                       void*                 data)
+{
+  rtems_rtl_obj_cache_t* symbols;
+  rtems_rtl_obj_cache_t* strings;
+  rtems_rtl_obj_sect_t*  strtab;
+  int                    globals;
+  int                    string_space;
+  char*                  string;
+  int                    sym;
+
+  strtab = rtems_rtl_obj_find_section (obj, ".strtab");
+  if (!strtab)
+  {
+    rtems_rtl_set_error (EINVAL, "no .strtab section");
+    return false;
+  }
+
+  rtems_rtl_obj_caches (&symbols, &strings, NULL);
+
+  if (!symbols || !strings)
+    return false;
+
+  /*
+   * Find the number of globals and the amount of string space
+   * needed. Also check for duplicate symbols.
+   */
+
+  globals      = 0;
+  string_space = 0;
+
+  for (sym = 0; sym < (sect->size / sizeof (Elf_Sym)); ++sym)
+  {
+    Elf_Sym     symbol;
+    off_t       off;
+    const char* name;
+    size_t      len;
+
+    off = obj->ooffset + sect->offset + (sym * sizeof (symbol));
+
+    if (!rtems_rtl_obj_cache_read_byval (symbols, fd, off,
+                                         &symbol, sizeof (symbol)))
+      return false;
+
+    off = obj->ooffset + strtab->offset + symbol.st_name;
+    len = RTEMS_RTL_ELF_STRING_MAX;
+
+    if (!rtems_rtl_obj_cache_read (strings, fd, off, (void**) &name, &len))
+      return false;
+
+    /*
+     * Only keep the functions and global or weak symbols.
+     */
+    if ((ELF_ST_TYPE (symbol.st_info) == STT_OBJECT) ||
+        (ELF_ST_TYPE (symbol.st_info) == STT_FUNC))
+    {
+      if ((ELF_ST_BIND (symbol.st_info) == STB_GLOBAL) ||
+          (ELF_ST_BIND (symbol.st_info) == STB_WEAK))
+      {
+        /*
+         * If there is a globally exported symbol already present and this
+         * symbol is not weak raise an error. If the symbol is weak and present
+         * globally ignore this symbol and use the global one and if it is not
+         * present take this symbol global or weak. We accept the first weak
+         * symbol we find and make it globally exported.
+         */
+        if (rtems_rtl_symbol_global_find (name) &&
+            (ELF_ST_BIND (symbol.st_info) != STB_WEAK))
+        {
+          rtems_rtl_set_error (ENOMEM, "duplicate global symbol: %s", name);
+          return false;
+        }
+        else
+        {
+          ++globals;
+          string_space += strlen (name) + 1;
+        }
+      }
+    }
+  }
+
+  if (globals)
+  {
+    rtems_rtl_obj_sym_t* gsym;
+
+    obj->global_size = globals * sizeof (rtems_rtl_obj_sym_t) + string_space;
+    obj->global_table = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_SYMBOL,
+                                             obj->global_size, true);
+    if (!obj->global_table)
+    {
+      obj->global_size = 0;
+      rtems_rtl_set_error (ENOMEM, "no memory for obj global syms");
+      return false;
+    }
+
+    obj->global_syms = globals;
+
+    for (sym = 0,
+           gsym = obj->global_table,
+           string = (((char*) obj->global_table) +
+                     (globals * sizeof (rtems_rtl_obj_sym_t)));
+         sym < (sect->size / sizeof (Elf_Sym));
+         ++sym)
+    {
+      Elf_Sym     symbol;
+      off_t       off;
+      const char* name;
+      size_t      len;
+
+      off = obj->ooffset + sect->offset + (sym * sizeof (symbol));
+
+      if (!rtems_rtl_obj_cache_read_byval (symbols, fd, off,
+                                           &symbol, sizeof (symbol)))
+      {
+        free (obj->global_table);
+        obj->global_table = NULL;
+        obj->global_syms = 0;
+        obj->global_size = 0;
+        return false;
+      }
+
+      off = obj->ooffset + strtab->offset + symbol.st_name;
+      len = RTEMS_RTL_ELF_STRING_MAX;
+
+      if (!rtems_rtl_obj_cache_read (strings, fd, off, (void**) &name, &len))
+        return false;
+
+      if (((ELF_ST_TYPE (symbol.st_info) == STT_OBJECT) ||
+           (ELF_ST_TYPE (symbol.st_info) == STT_FUNC)) &&
+          ((ELF_ST_BIND (symbol.st_info) == STB_GLOBAL) ||
+           (ELF_ST_BIND (symbol.st_info) == STB_WEAK)))
+      {
+        rtems_rtl_obj_sect_t* symsect;
+        symsect = rtems_rtl_obj_find_section_by_index (obj, symbol.st_shndx);
+        if (!symsect)
+        {
+          free (obj->global_table);
+          obj->global_table = NULL;
+          obj->global_syms = 0;
+          obj->global_size = 0;
+          rtems_rtl_set_error (EINVAL, "sym section not found");
+          return false;
+        }
+
+        rtems_chain_set_off_chain (&gsym->node);
+
+        memcpy (string, name, strlen (name) + 1);
+        gsym->name = string;
+        string += strlen (name) + 1;
+        gsym->value = symbol.st_value + (uint8_t*) symsect->base;
+        gsym->data = symbol.st_info;
+
+        if (rtems_rtl_trace (RTEMS_RTL_TRACE_SYMBOL))
+          printf ("rtl: sym:add:%-2d name:%-2d:%-20s bind:%-2d type:%-2d val:%8p sect:%d size:%d\n",
+                  sym, (int) symbol.st_name, gsym->name,
+                  (int) ELF_ST_BIND (symbol.st_info),
+                  (int) ELF_ST_TYPE (symbol.st_info),
+                  gsym->value, symbol.st_shndx,
+                  (int) symbol.st_size);
+
+        ++gsym;
+      }
+    }
+
+    rtems_rtl_symbol_obj_add (obj);
+  }
+
+  return true;
+}
+
+static bool
+rtems_rtl_elf_loader (rtems_rtl_obj_t*      obj,
+                      int                   fd,
+                      rtems_rtl_obj_sect_t* sect,
+                      void*                 data)
+{
+  uint8_t* base_offset;
+  size_t   len;
+
+  if (lseek (fd, obj->ooffset + sect->offset, SEEK_SET) < 0)
+  {
+    rtems_rtl_set_error (errno, "section load seek failed");
+    return false;
+  }
+
+  base_offset = sect->base;
+  len = sect->size;
+
+  while (len)
+  {
+    ssize_t r = read (fd, base_offset, len);
+    if (r <= 0)
+    {
+      rtems_rtl_set_error (errno, "section load read failed");
+      return false;
+    }
+    base_offset += r;
+    len -= r;
+  }
+
+  return true;
+}
+
+static bool
+rtems_rtl_elf_parse_sections (rtems_rtl_obj_t* obj, int fd, Elf_Ehdr* ehdr)
+{
+  rtems_rtl_obj_cache_t* sects;
+  rtems_rtl_obj_cache_t* strings;
+  int                    section;
+  off_t                  sectstroff;
+  off_t                  off;
+  Elf_Shdr               shdr;
+
+  rtems_rtl_obj_caches (&sects, &strings, NULL);
+
+  if (!sects || !strings)
+    return false;
+
+  /*
+   * Get the offset to the section string table.
+   */
+  off = obj->ooffset + ehdr->e_shoff + (ehdr->e_shstrndx * ehdr->e_shentsize);
+
+  if (!rtems_rtl_obj_cache_read_byval (sects, fd, off, &shdr, sizeof (shdr)))
+    return false;
+
+  if (shdr.sh_type != SHT_STRTAB)
+  {
+    rtems_rtl_set_error (EINVAL, "bad .sectstr section type");
+    return false;
+  }
+
+  sectstroff = obj->ooffset + shdr.sh_offset;
+
+  for (section = 0; section < ehdr->e_shnum; ++section)
+  {
+    uint32_t flags;
+
+    off = obj->ooffset + ehdr->e_shoff + (section * ehdr->e_shentsize);
+
+    if (!rtems_rtl_obj_cache_read_byval (sects, fd, off, &shdr, sizeof (shdr)))
+      return false;
+
+    flags = 0;
+
+    switch (shdr.sh_type)
+    {
+      case SHT_NULL:
+        /*
+         * Ignore.
+         */
+        break;
+
+      case SHT_PROGBITS:
+        /*
+         * There are 2 program bits sections. One is the program text and the
+         * other is the program data. The program text is flagged
+         * alloc/executable and the program data is flagged alloc/writable.
+         */
+        if ((shdr.sh_flags & SHF_ALLOC) == SHF_ALLOC)
+        {
+          if ((shdr.sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR)
+            flags = RTEMS_RTL_OBJ_SECT_TEXT | RTEMS_RTL_OBJ_SECT_LOAD;
+          else if ((shdr.sh_flags & SHF_WRITE) == SHF_WRITE)
+            flags = RTEMS_RTL_OBJ_SECT_DATA | RTEMS_RTL_OBJ_SECT_LOAD;
+          else
+            flags = RTEMS_RTL_OBJ_SECT_CONST | RTEMS_RTL_OBJ_SECT_LOAD;
+        }
+        break;
+
+      case SHT_NOBITS:
+        /*
+         * There is 1 NOBIT section which is the .bss section. There is nothing
+         * but a definition as the .bss is just a clear region of memory.
+         */
+        if ((shdr.sh_flags & (SHF_ALLOC | SHF_WRITE)) == (SHF_ALLOC | SHF_WRITE))
+          flags = RTEMS_RTL_OBJ_SECT_BSS | RTEMS_RTL_OBJ_SECT_ZERO;
+        break;
+
+      case SHT_RELA:
+        flags = RTEMS_RTL_OBJ_SECT_RELA;
+        break;
+
+      case SHT_REL:
+        /*
+         * The sh_link holds the section index for the symbol table. The sh_info
+         * holds the section index the relocations apply to.
+         */
+        flags = RTEMS_RTL_OBJ_SECT_REL;
+        break;
+
+      case SHT_SYMTAB:
+        flags = RTEMS_RTL_OBJ_SECT_SYM;
+        break;
+
+      case SHT_STRTAB:
+        flags = RTEMS_RTL_OBJ_SECT_STR;
+        break;
+
+      default:
+        printf ("rtl: unsupported section: %2d: type=%02d flags=%02x\n",
+                section, (int) shdr.sh_type, (int) shdr.sh_flags);
+        break;
+    }
+
+    if (flags != 0)
+    {
+      char*  name;
+      size_t len;
+
+      len = RTEMS_RTL_ELF_STRING_MAX;
+      if (!rtems_rtl_obj_cache_read (strings, fd,
+                                     sectstroff + shdr.sh_name,
+                                     (void**) &name, &len))
+        return false;
+
+      if (strcmp (".ctors", name) == 0)
+        flags |= RTEMS_RTL_OBJ_SECT_CTOR;
+      if (strcmp (".dtors", name) == 0)
+        flags |= RTEMS_RTL_OBJ_SECT_DTOR;
+
+      if (!rtems_rtl_obj_add_section (obj, section, name,
+                                      shdr.sh_size, shdr.sh_offset,
+                                      shdr.sh_addralign, shdr.sh_link,
+                                      shdr.sh_info, flags))
+        return false;
+    }
+  }
+
+  return true;
+}
+
+bool
+rtems_rtl_elf_file_check (rtems_rtl_obj_t* obj, int fd)
+{
+  rtems_rtl_obj_cache_t* header;
+  Elf_Ehdr               ehdr;
+
+  rtems_rtl_obj_caches (&header, NULL, NULL);
+
+  if (!rtems_rtl_obj_cache_read_byval (header, fd, obj->ooffset,
+                                       &ehdr, sizeof (ehdr)))
+    return false;
+
+  /*
+   * Check we have a valid ELF file.
+   */
+  if ((memcmp (ELFMAG, ehdr.e_ident, SELFMAG) != 0)
+      || ehdr.e_ident[EI_CLASS] != ELFCLASS)
+  {
+    return false;
+  }
+
+  if ((ehdr.e_ident[EI_VERSION] != EV_CURRENT)
+      || (ehdr.e_version != EV_CURRENT)
+      || (ehdr.e_ident[EI_DATA] != ELFDEFNNAME (MACHDEP_ENDIANNESS)))
+  {
+    return false;
+  }
+
+  return true;
+}
+
+bool rtems_rtl_elf_load_details (rtems_rtl_obj_t* obj)
+{
+  rtems_chain_control* sections = NULL;
+  rtems_chain_node*    node = NULL;
+  size_t               mask = 0;
+  struct link_map*     l = NULL;
+  int                  sec_num = 0;
+  int                  i = 0;
+
+  /* caculate the size of sections' name. */
+
+  for (mask = RTEMS_RTL_OBJ_SECT_TEXT;
+       mask <= RTEMS_RTL_OBJ_SECT_BSS;
+       mask <<= 1)
+  {
+    sections = &obj->sections;
+    node = rtems_chain_first (sections);
+    while (!rtems_chain_is_tail (sections, node))
+    {
+      rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
+
+      if ((sect->size != 0) && ((sect->flags & mask) != 0))
+      {
+        ++sec_num;
+      }
+      node = rtems_chain_next (node);
+    }
+  }
+
+  obj->obj_num = 1;
+  obj->detail = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
+                                     sizeof(struct link_map) +
+                                     sec_num * sizeof (section_detail), true);
+  if (!obj->detail)
+  {
+    rtems_rtl_set_error (ENOMEM, "no memory for obj global syms");
+    return false;
+  }
+
+  l = (struct link_map*) obj->detail;
+  l->name = obj->oname;
+  l->sec_num = sec_num;
+  l->sec_detail = (section_detail*) (l + 1);
+  l->rpathlen = 0;
+  l->rpath = NULL;
+  l->l_next = NULL;
+  l->l_prev = NULL;
+  l->sec_addr[rap_text] = obj->text_base;
+  l->sec_addr[rap_const] = obj->const_base;
+  l->sec_addr[rap_data] = obj->data_base;
+  l->sec_addr[rap_bss] = obj->bss_base;
+
+
+  section_detail* sd = l->sec_detail;
+  sections = &obj->sections;
+  node = rtems_chain_first (sections);
+  for (mask = RTEMS_RTL_OBJ_SECT_TEXT;
+       mask <= RTEMS_RTL_OBJ_SECT_BSS;
+       mask <<= 1)
+  {
+    sections = &obj->sections;
+    node = rtems_chain_first (sections);
+    while (!rtems_chain_is_tail (sections, node))
+    {
+      rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
+
+      if ((sect->size != 0) && ((sect->flags & mask) != 0))
+      {
+        sd[i].name = sect->name;
+        sd[i].size = sect->size;
+        if (mask == RTEMS_RTL_OBJ_SECT_TEXT)
+        {
+          sd[i].rap_id = rap_text;
+          sd[i].offset = sect->base - obj->text_base;
+        }
+        if (mask == RTEMS_RTL_OBJ_SECT_CONST)
+        {
+          sd[i].rap_id = rap_const;
+          sd[i].offset = sect->base - obj->const_base;
+        }
+        if (mask == RTEMS_RTL_OBJ_SECT_DATA)
+        {
+          sd[i].rap_id = rap_data;
+          sd[i].offset = sect->base - obj->data_base;
+        }
+        if (mask == RTEMS_RTL_OBJ_SECT_BSS)
+        {
+          sd[i].rap_id = rap_bss;
+          sd[i].offset = sect->base - obj->bss_base;
+        }
+
+        ++i;
+      }
+      node = rtems_chain_next (node);
+    }
+  }
+
+  return true;
+}
+
+bool
+rtems_rtl_elf_file_load (rtems_rtl_obj_t* obj, int fd)
+{
+  rtems_rtl_obj_cache_t* header;
+  Elf_Ehdr               ehdr;
+
+  rtems_rtl_obj_caches (&header, NULL, NULL);
+
+  if (!rtems_rtl_obj_cache_read_byval (header, fd, obj->ooffset,
+                                       &ehdr, sizeof (ehdr)))
+    return false;
+
+  /*
+   * Check we have a valid ELF file.
+   */
+  if ((memcmp (ELFMAG, ehdr.e_ident, SELFMAG) != 0)
+      || ehdr.e_ident[EI_CLASS] != ELFCLASS)
+  {
+    rtems_rtl_set_error (EINVAL, "invalid ELF file format");
+    return false;
+  }
+
+  if ((ehdr.e_ident[EI_VERSION] != EV_CURRENT)
+      || (ehdr.e_version != EV_CURRENT)
+      || (ehdr.e_ident[EI_DATA] != ELFDEFNNAME (MACHDEP_ENDIANNESS)))
+  {
+    rtems_rtl_set_error (EINVAL, "unsupported ELF file version");
+    return false;
+  }
+
+  if (!rtems_rtl_elf_machine_check (&ehdr))
+  {
+    rtems_rtl_set_error (EINVAL, "unsupported machine type");
+    return false;
+  }
+
+  if (ehdr.e_type == ET_DYN)
+  {
+    rtems_rtl_set_error (EINVAL, "unsupported ELF file type");
+    return false;
+  }
+
+  if (ehdr.e_phentsize != 0)
+  {
+    rtems_rtl_set_error (EINVAL, "ELF file contains program headers");
+    return false;
+  }
+
+  if (ehdr.e_shentsize != sizeof (Elf_Shdr))
+  {
+    rtems_rtl_set_error (EINVAL, "invalid ELF section header size");
+    return false;
+  }
+
+  /*
+   * Parse the section information first so we have the memory map of the object
+   * file and the memory allocated. Any further allocations we make to complete
+   * the load will not fragment the memory.
+   */
+  if (!rtems_rtl_elf_parse_sections (obj, fd, &ehdr))
+    return false;
+
+  obj->entry = (void*)(uintptr_t) ehdr.e_entry;
+
+  if (!rtems_rtl_obj_load_sections (obj, fd, rtems_rtl_elf_loader, &ehdr))
+    return false;
+
+  if (!rtems_rtl_obj_load_symbols (obj, fd, rtems_rtl_elf_symbols, &ehdr))
+    return false;
+
+  if (!rtems_rtl_obj_relocate (obj, fd, rtems_rtl_elf_relocator, &ehdr))
+    return false;
+
+  if (!rtems_rtl_elf_load_details (obj))
+  {
+    return false;
+  }
+
+  return true;
+}
+
+rtems_rtl_loader_format_t*
+rtems_rtl_elf_file_sig (void)
+{
+  return &elf_sig;
+}
diff --git a/cpukit/libdl/rtl-elf.h b/cpukit/libdl/rtl-elf.h
new file mode 100644
index 0000000..115c05a
--- /dev/null
+++ b/cpukit/libdl/rtl-elf.h
@@ -0,0 +1,165 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker ELF Headers
+ */
+
+#if !defined (_RTEMS_RTL_ELF_H_)
+#define _RTEMS_RTL_ELF_H_
+
+#include "rtl-fwd.h"
+#include "rtl-obj-fwd.h"
+#include "rtl-sym.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ ** Imported NetBSD ELF Specifics Start.
+ **/
+
+/*
+ * Always 32bit for RTEMS at the moment. Do not add '()'. Leave plain.
+ */
+#define ELFSIZE 32
+
+/*
+ * Define _STANDALONE then remove after.
+ */
+#define _STANDALONE 1
+
+#include <sys/cdefs.h>
+#include <sys/exec_elf.h>
+
+#undef _STANDALONE
+
+/**
+ ** Imported NetBSD ELF Specifics End.
+ **/
+
+/**
+ * Maximum string length. This a read buffering limit rather than a
+ * specific ELF length. I hope this is ok as I am concerned about
+ * some C++ symbol lengths.
+ */
+#define RTEMS_RTL_ELF_STRING_MAX (256)
+
+/**
+ * Architecture specific handler to check is a relocation record's type is
+ * required to resolve a symbol.
+ *
+ * @param type The type field in the relocation record.
+ * @retval true The relocation record require symbol resolution.
+ * @retval false The relocation record does not require symbol resolution.
+ */
+bool rtems_rtl_elf_rel_resolve_sym (Elf_Word type);
+
+/**
+ * Architecture specific relocation handler compiled in for a specific
+ * architecture by the build system. The handler applies the relocation
+ * to the target.
+ *
+ * @param obj The object file being relocated.
+ * @param rel The ELF relocation record.
+ * @param sect The section of the object file the relocation is for.
+ * @param symname The symbol's name.
+ * @param syminfo The ELF symbol info field.
+ * @param symvalue If a symbol is referenced, this is the symbols value.
+ * @retval bool The relocation has been applied.
+ * @retval bool The relocation could not be applied.
+ */
+bool rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t*      obj,
+                                 const Elf_Rel*              rel,
+                                 const rtems_rtl_obj_sect_t* sect,
+                                 const char*                 symname,
+                                 const Elf_Byte              syminfo,
+                                 const Elf_Word              symvalue);
+
+/**
+ * Architecture specific relocation handler compiled in for a specific
+ * architecture by the build system. The handler applies the relocation
+ * to the target.
+ *
+ * @param obj The object file being relocated.
+ * @param rela The ELF addend relocation record.
+ * @param sect The section of the object file the relocation is for.
+ * @param symname The symbol's name.
+ * @param syminfo The ELF symbol info field.
+ * @param symvalue If a symbol is referenced, this is the symbols value.
+ * @retval bool The relocation has been applied.
+ * @retval bool The relocation could not be applied.
+ */
+bool rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t*      obj,
+                                  const Elf_Rela*             rela,
+                                  const rtems_rtl_obj_sect_t* sect,
+                                  const char*                 symname,
+                                  const Elf_Byte              syminfo,
+                                  const Elf_Word              symvalue);
+
+/**
+ * Find the symbol. The symbol is passed as an ELF type symbol with the name
+ * and the value returned is the absolute address of the symbol.
+ *
+ * If the symbol type is STT_NOTYPE the symbol references a global symbol. The
+ * gobal symbol table is searched to find it and that value returned. If the
+ * symbol is local to the object module the section for the symbol is located
+ * and it's base added to the symbol's value giving an absolute location.
+ *
+ * @param obj The object the symbol is being resolved for.
+ * @param sym The ELF type symbol.
+ * @param symname The sym's name read from the symbol string table.
+ * @param value Return the value of the symbol. Only valid if the return value
+ *              is true.
+ * @retval true The symbol resolved.
+ * @retval false The symbol could not be result. The RTL error is set.
+ */
+bool rtems_rtl_elf_find_symbol (rtems_rtl_obj_t* obj,
+                                const Elf_Sym*   sym,
+                                const char*      symname,
+                                Elf_Word*        value);
+
+/**
+ * The ELF format check handler.
+ *
+ * @param obj The object being checked.
+ * @param fd The file descriptor.
+ */
+bool rtems_rtl_elf_file_check (rtems_rtl_obj_t* obj, int fd);
+
+/**
+ * The ELF file details handler.
+ *
+ * @param obj Load the details of the obj.
+ */
+bool rtems_rtl_elf_load_details (rtems_rtl_obj_t* obj);
+
+/**
+ * The ELF format load handler.
+ *
+ * @param obj The object to load.
+ * @param fd The file descriptor.
+ */
+bool rtems_rtl_elf_file_load (rtems_rtl_obj_t* obj, int fd);
+
+/**
+ * The ELF format signature handler.
+ *
+ * @return rtems_rtl_loader_format_t* The format's signature.
+ */
+rtems_rtl_loader_format_t* rtems_rtl_elf_file_sig (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/libdl/rtl-error.c b/cpukit/libdl/rtl-error.c
new file mode 100644
index 0000000..bc2e3e4
--- /dev/null
+++ b/cpukit/libdl/rtl-error.c
@@ -0,0 +1,47 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtl
+ *
+ * @brief RTEMS Run-Time Linker Error
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-error.h"
+
+void
+rtems_rtl_set_error (int error, const char* format, ...)
+{
+  rtems_rtl_data_t* rtl = rtems_rtl_lock ();
+  va_list           ap;
+  va_start (ap, format);
+  rtl->last_errno = error;
+  vsnprintf (rtl->last_error, sizeof (rtl->last_error), format, ap);
+  rtems_rtl_unlock ();
+  va_end (ap);
+}
+
+int
+rtems_rtl_get_error (char* message, size_t max_message)
+{
+  rtems_rtl_data_t* rtl = rtems_rtl_lock ();
+  int               last_errno = rtl->last_errno;
+  strncpy (message, rtl->last_error, sizeof (rtl->last_error));
+  rtems_rtl_unlock ();
+  return last_errno;
+}
+
diff --git a/cpukit/libdl/rtl-error.h b/cpukit/libdl/rtl-error.h
new file mode 100644
index 0000000..a17db59
--- /dev/null
+++ b/cpukit/libdl/rtl-error.h
@@ -0,0 +1,44 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Error
+ */
+
+#if !defined (_RTEMS_RTL_ERROR_H_)
+#define _RTEMS_RTL_ERROR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#if __GNUC__
+#define RTEMS_RTL_PRINTF_ATTR   __attribute__((__format__(__printf__,2,3)))
+#else
+#define RTEMS_RTL_PRINTF_ATTR
+#endif
+
+/**
+ * Sets the error. 
+ *
+ * Assumes the RTL has been locked.
+ *
+ * @param error The errno error number.
+ * @param format The error format string.
+ * @param ... The variable arguments that depend on the format string.
+ */
+void rtems_rtl_set_error (int error, const char* format, ...) RTEMS_RTL_PRINTF_ATTR;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/libdl/rtl-find-file.c b/cpukit/libdl/rtl-find-file.c
new file mode 100644
index 0000000..589be40
--- /dev/null
+++ b/cpukit/libdl/rtl-find-file.c
@@ -0,0 +1,110 @@
+/*
+ *  COPYRIGHT (c) 2012-2013 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtl
+ *
+ * @brief RTEMS Run-Time Linker Error
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <rtems/libio_.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-find-file.h"
+#include "rtl-error.h"
+#include "rtl-string.h"
+#include "rtl-trace.h"
+
+#if WAF_BUILD
+#define rtems_filesystem_is_delimiter rtems_filesystem_is_separator
+#endif
+
+bool
+rtems_rtl_find_file (const char*  name,
+                     const char*  paths,
+                     const char** file_name,
+                     size_t*      size)
+{
+  struct stat sb;
+
+  *file_name = NULL;
+  *size = 0;
+
+  if (rtems_filesystem_is_delimiter (name[0]) || (name[0] == '.'))
+  {
+    if (stat (name, &sb) == 0)
+      *file_name = rtems_rtl_strdup (name);
+  }
+  else if (paths)
+  {
+    const char* start;
+    const char* end;
+    int         len;
+    char*       fname;
+
+    start = paths;
+    end = start + strlen (paths);
+    len = strlen (name);
+
+    while (!*file_name && (start != end))
+    {
+      const char* delimiter = strchr (start, ':');
+
+      if (delimiter == NULL)
+        delimiter = end;
+
+      /*
+       * Allocate the path fragment, separator, name, terminating nul. Form the
+       * path then see if the stat call works.
+       */
+
+      fname = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
+                                   (delimiter - start) + 1 + len + 1, true);
+      if (!fname)
+      {
+        rtems_rtl_set_error (ENOMEM, "no memory searching for file");
+        return false;
+      }
+
+      memcpy (fname, start, delimiter - start);
+      fname[delimiter - start] = '/';
+      memcpy (fname + (delimiter - start) + 1, name, len);
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
+        printf ("rtl: find-file: path: %s\n", fname);
+
+      if (stat (fname, &sb) < 0)
+        rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, fname);
+      else
+        *file_name = fname;
+
+      start = delimiter;
+      if (start != end)
+        ++start;
+    }
+  }
+
+  if (!*file_name)
+    return false;
+
+  *size = sb.st_size;
+
+  return true;
+}
diff --git a/cpukit/libdl/rtl-find-file.h b/cpukit/libdl/rtl-find-file.h
new file mode 100644
index 0000000..fc8a9dc
--- /dev/null
+++ b/cpukit/libdl/rtl-find-file.h
@@ -0,0 +1,45 @@
+/*
+ *  COPYRIGHT (c) 2012-2013 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object Support.
+ */
+
+#if !defined (_RTEMS_RTL_FIND_FILE_H_)
+#define _RTEMS_RTL_FIND_FILE_H_
+
+#include <rtems.h>
+#include <rtems/chain.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Find a file on disk given a name and a path.
+ *
+ * @param name The file name to find. Can be relative or absolute.
+ * @param paths The paths to search.
+ * @param file_name Place the full path in this location if found.
+ * @param size The size of the file if found as returned by the 'stat' call.
+ * @retval true The file was found.
+ * @retval false The file was not found.
+ */
+bool rtems_rtl_find_file (const char*  name,
+                          const char*  paths,
+                          const char** file_name,
+                          size_t*      size);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/libdl/rtl-fwd.h b/cpukit/libdl/rtl-fwd.h
new file mode 100644
index 0000000..115ba8c
--- /dev/null
+++ b/cpukit/libdl/rtl-fwd.h
@@ -0,0 +1,33 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker ELF Headers
+ */
+
+#if !defined (_RTEMS_RTL_FWD_H_)
+#define _RTEMS_RTL_FWD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * The forward declaration of the obj structure.
+ */
+struct rtems_rtl_data_s;
+typedef struct rtems_rtl_data_s rtems_rtl_data_t;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/libdl/rtl-indirect-ptr.h b/cpukit/libdl/rtl-indirect-ptr.h
new file mode 100644
index 0000000..5a5b43b
--- /dev/null
+++ b/cpukit/libdl/rtl-indirect-ptr.h
@@ -0,0 +1,235 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Indirect Pointer Management allows memory
+ *        compaction in the allocator. 
+ */
+
+#if !defined (_RTEMS_RTL_INDIRECT_PTR_H_)
+#define _RTEMS_RTL_INDIRECT_PTR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <rtems/chain.h>
+
+/**
+ * The RTL Indirect pointer.
+ */
+struct rtems_rtl_ptr_s {
+  rtems_chain_node node;     /**< Indirect pointers are held on lists. */
+  void*            pointer;  /**< The actual pointer. */
+};
+
+typedef struct rtems_rtl_ptr_s rtems_rtl_ptr_t;
+
+/**
+ * The RTL Indirect size and pointer.
+ */
+struct rtems_rtl_sptr_s {
+  rtems_rtl_ptr_t  ptr;      /**< The indirect pointer. */
+  size_t           size;     /**< The size of the memory block. */
+};
+
+typedef struct rtems_rtl_sptr_s rtems_rtl_sptr_t;
+
+/**
+ * A chain of indirect pointers for users to chain in applications.
+ *
+ * @note The chain the pointer is on is internal to the allocator and cannot be
+ *       used by applications.
+ */
+struct rtems_rtl_ptr_chain_s {
+  rtems_chain_node node;  /**< Chain of indirect pointers. */
+  rtems_rtl_ptr_t  ptr;   /**< The indirect pointer. */
+};
+
+typedef struct rtems_rtl_ptr_chain_s rtems_rtl_ptr_chain_t;
+
+/**
+ * A chain of indirect sized pointers for users to chain in applications.
+ *
+ * @note The chain the pointer is on is internal to the allocator and cannot be
+ *       used by applications.
+ */
+struct rtems_rtl_sptr_chain_s {
+  rtems_chain_node node;  /**< Chain of indirect pointers. */
+  rtems_rtl_sptr_t  ptr;  /**< The indirect pointer. */
+};
+
+typedef struct rtems_rtl_sptr_chain_s rtems_rtl_sptr_chain_t;
+
+/**
+ * Get the pointer given an indirect handle.
+ *
+ * @param handle The handle the pointer is returned from.
+ * @return void* The pointer held in the handle.
+ */
+static inline void* rtems_rtl_ptr_get (rtems_rtl_ptr_t* handle)
+{
+  return handle->pointer;
+}
+
+/**
+ * Set the pointer given an indirect handle and the pointer.
+ *
+ * @param handle The handle the pointer is returned from.
+ * @param pointer The pointer to set in the handle.
+ */
+static inline void rtems_rtl_ptr_set (rtems_rtl_ptr_t* handle, void* pointer)
+{
+  handle->pointer = pointer;
+}
+
+/**
+ * Initialise the indirect handle.
+ *
+ * @param handle The handle to initialise.
+ */
+static inline void rtems_rtl_ptr_init (rtems_rtl_ptr_t* handle)
+{
+  rtems_chain_set_off_chain (&handle->node);
+  handle->pointer = NULL;
+}
+
+/**
+ * Is the indirect handle NULL ?
+ *
+ * @param handle The handle to test.
+ * @return bool True if the pointer is NULL.
+ */
+static inline bool rtems_rtl_ptr_null (rtems_rtl_ptr_t* handle)
+{
+  return handle->pointer == NULL;
+}
+
+/**
+ * Move the allocated pointer from one handle to another. The source handle is
+ * cleared and removed from the list of handles.
+ *
+ * @param src The source handle to move the pointer from.
+ * @param dst The destination handle to receive the pointer.
+ */
+static inline void rtems_rtl_ptr_move (rtems_rtl_ptr_t* dst, rtems_rtl_ptr_t* src)
+{
+  /*
+   * We do not know which chain the src handle resides on so insert the dst
+   * handle after the src handle then extract the src handle.
+   */
+  rtems_chain_insert_unprotected (&src->node, &dst->node);
+  rtems_chain_extract_unprotected (&src->node);
+  dst->pointer = src->pointer;
+  rtems_rtl_ptr_init (src);
+}
+
+/**
+ * Return the pointer as the type provided.
+ *
+ * @param _h The handle.
+ * @param _t The type.
+ */
+#define rtems_rtl_ptr_type_get(_h, _t) ((_t*) rtems_rtl_ptr_get (_h))
+
+/**
+ * Get the pointer given an indirect handle.
+ *
+ * @param handle The handle the pointer is returned from.
+ * @return void* The pointer held in the handle.
+ */
+static inline void* rtems_rtl_sptr_get (rtems_rtl_sptr_t* handle)
+{
+  return rtems_rtl_ptr_get (&handle->ptr);
+}
+
+/**
+ * Set the pointer given an indirect handle and the pointer.
+ *
+ * @param handle The handle the pointer is returned from.
+ * @param pointer The pointer to set in the handle.
+ */
+static inline void rtems_rtl_sptr_set (rtems_rtl_sptr_t* handle, void* pointer)
+{
+  rtems_rtl_ptr_set (&handle->ptr, pointer);
+}
+
+/**
+ * Initialise the indirect handle.
+ *
+ * @param handle The handle to initialise.
+ */
+static inline void rtems_rtl_sptr_init (rtems_rtl_sptr_t* handle)
+{
+  rtems_rtl_ptr_init (&handle->ptr);
+  handle->size = 0;
+}
+
+/**
+ * Is the indirect handle NULL ?
+ *
+ * @param handle The handle to test.
+ * @return bool True if the pointer is NULL.
+ */
+static inline bool rtems_rtl_sptr_null (rtems_rtl_sptr_t* handle)
+{
+  return rtems_rtl_ptr_null (&handle->ptr);
+}
+
+/**
+ * Move the allocated pointer from one handle to another. The source handle is
+ * cleared and removed from the list of handles.
+ *
+ * @param src The source handle to move the pointer from.
+ * @param dst The destination handle to receive the pointer.
+ */
+static inline void rtems_rtl_sptr_move (rtems_rtl_sptr_t* dst, rtems_rtl_sptr_t* src)
+{
+  rtems_rtl_ptr_move (&dst->ptr, &src->ptr);
+  dst->size = src->size;
+  src->size = 0;
+}
+
+/**
+ * Get the size.
+ *
+ * @param handle The handle to get the size from.
+ * @return size_t The size_t.
+ */
+static inline size_t rtems_rtl_sptr_get_size (rtems_rtl_sptr_t* handle)
+{
+  return handle->size;
+}
+
+/**
+ * Set the size.
+ *
+ * @param handle The handle to set the size.
+ * @param size The size to set..
+ */
+static inline void rtems_rtl_sptr_set_size (rtems_rtl_sptr_t* handle, size_t size)
+{
+  handle->size = size;
+}
+
+/**
+ * Return the pointer as the type provided.
+ *
+ * @param _h The handle.
+ * @param _t The type.
+ */
+#define rtems_rtl_sptr_type_get(_h, _t) ((_t*) rtems_rtl_sptr_get (_h))
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/libdl/rtl-mdreloc-arm.c b/cpukit/libdl/rtl-mdreloc-arm.c
new file mode 100644
index 0000000..692c829
--- /dev/null
+++ b/cpukit/libdl/rtl-mdreloc-arm.c
@@ -0,0 +1,323 @@
+/*
+ * Taken from NetBSD and stripped of the relocations not needed on RTEMS.
+ */
+
+/*  $NetBSD: mdreloc.c,v 1.33 2010/01/14 12:12:07 skrll Exp $  */
+
+#include <sys/cdefs.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-elf.h"
+#include "rtl-error.h"
+#include "rtl-trace.h"
+
+/*
+ * It is possible for the compiler to emit relocations for unaligned data.
+ * We handle this situation with these inlines.
+ */
+#define	RELOC_ALIGNED_P(x) \
+	(((uintptr_t)(x) & (sizeof(void *) - 1)) == 0)
+
+static inline Elf_Addr
+load_ptr(void *where)
+{
+	Elf_Addr res;
+
+	memcpy(&res, where, sizeof(res));
+
+	return (res);
+}
+
+static inline void
+store_ptr(void *where, Elf_Addr val)
+{
+
+	memcpy(where, &val, sizeof(val));
+}
+
+/*
+ * The address of Thumb function symbols is it's real address plus one.
+ * This is done by compiler, thus do not consider symtype here.
+ */
+static inline int
+isThumb(Elf_Word symvalue)
+{
+  if ((symvalue & 0x1) == 0x1)
+    return true;
+  else return false;
+}
+
+bool
+rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
+{
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t*      obj,
+                             const Elf_Rela*             rela,
+                             const rtems_rtl_obj_sect_t* sect,
+                             const char*                 symname,
+                             const Elf_Byte              syminfo,
+                             const Elf_Word              symvalue)
+{
+  rtems_rtl_set_error (EINVAL, "rela type record not supported");
+  return false;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t*      obj,
+                            const Elf_Rel*              rel,
+                            const rtems_rtl_obj_sect_t* sect,
+                            const char*                 symname,
+                            const Elf_Byte              syminfo,
+                            const Elf_Word              symvalue)
+{
+  Elf_Addr *where;
+  Elf_Addr tmp;
+  Elf_Word insn, addend;
+  Elf_Word sign, i1, i2;
+  uint16_t lower_insn, upper_insn;
+
+  where = (Elf_Addr *)(sect->base + rel->r_offset);
+
+  switch (ELF_R_TYPE(rel->r_info)) {
+		case R_TYPE(NONE):
+			break;
+
+    case R_TYPE(CALL):    /* BL/BLX */
+    case R_TYPE(JUMP24):  /* B/BL<cond> */
+      insn = *where;
+
+      if (insn & 0x00800000)
+        addend = insn | 0xff000000;
+      else addend = insn & 0x00ffffff;
+
+      if (isThumb(symvalue)) {
+        if ((insn & 0xfe000000) == 0xfa000000);         /* Already blx */
+        else {
+          if ((insn & 0xff000000) == 0xeb000000) {      /* BL <label> */
+            *where = (insn & 0x00ffffff) | 0xfa000000;  /* BL-->BLX */
+          } else {
+            printf("JUMP24 is not suppored from arm to thumb\n");
+            return false;
+          }
+        }
+      }
+
+      tmp = symvalue + (addend << 2) - (Elf_Addr)where;
+      tmp = (Elf_Sword)tmp >> 2;
+
+      if (((Elf_Sword)tmp > 0x7fffff) || ((Elf_Sword)tmp < -0x800000)) {
+        printf("CALL/JUMP24 Overflow\n");
+        return false;
+      }
+
+      *where = (*where & 0xff000000) | (tmp & 0xffffff);
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: JUMP24/PC24/CALL %p @ %p in %s\n",
+                (void *)*where, where, rtems_rtl_obj_oname (obj));
+
+      break;
+
+    case R_TYPE(V4BX):
+      /* Miscellaneous, ignore */
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
+        printf ("rtl: V4BX %p @ %p in %s\n",
+                (void *)*where, where, rtems_rtl_obj_oname (obj));
+      }
+      break;
+
+    case R_TYPE(MOVT_ABS):
+    case R_TYPE(MOVW_ABS_NC):
+      insn = *where;
+
+      addend = ((insn >> 4) & 0xf000) | (insn & 0x0fff);
+      if (addend & 0x8000)
+        addend |= 0xffff0000;
+
+      tmp = symvalue + addend;
+
+      if (ELF_R_TYPE(rel->r_info) == R_TYPE(MOVW_ABS_NC))
+        tmp &= 0xffff;
+      else {
+        tmp = (Elf_Sword)tmp >> 16;
+        if (((Elf_Sword)tmp > 0x7fff) || ((Elf_Sword)tmp < -0x8000)) {
+          printf("MOVT_ABS Overflow\n");
+          return false;
+        }
+      }
+
+      *where = (insn & 0xfff0f000) | ((tmp & 0xf000) << 4) | (tmp & 0xfff);
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: MOVT_ABS/MOVW_ABS_NC %p @ %p in %s\n",
+                (void *)*where, where, rtems_rtl_obj_oname (obj));
+      break;
+
+
+    case R_TYPE(REL32):     /* word32 (S + A) | T - P */
+    case R_TYPE(ABS32):     /* word32 (S + A) | T */
+    case R_TYPE(GLOB_DAT):  /* word32 (S + A) | T */
+      if (__predict_true(RELOC_ALIGNED_P(where))) {
+        tmp = *where + symvalue;
+        if (isThumb(symvalue))
+          tmp |= 1;
+        if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32))
+          tmp -= (Elf_Addr)where;
+        *where = tmp;
+      } else {
+        tmp = load_ptr(where) + symvalue;
+        if (isThumb(symvalue))
+          tmp |= 1;
+        if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32))
+          tmp -= (Elf_Addr)where;
+        store_ptr(where, tmp);
+      }
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: REL32/ABS32/GLOB_DAT %p @ %p in %s",
+                (void *)tmp, where, rtems_rtl_obj_oname (obj));
+      break;
+
+    case R_TYPE(THM_MOVT_ABS):
+    case R_TYPE(THM_MOVW_ABS_NC):
+      upper_insn = *(uint16_t *)where;
+      lower_insn = *((uint16_t *)where + 1);
+
+      addend = ((upper_insn & 0x000f) << 12) | ((upper_insn & 0x0400) << 1) |
+               ((lower_insn & 0x7000) >> 4) | (lower_insn & 0x00ff);
+      addend = (addend ^ 0x8000) - 0x8000;
+
+      tmp = addend + symvalue;
+      if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS)
+        tmp >>= 16;
+
+      *(uint16_t *)where = (uint16_t)((upper_insn & 0xfbf0) |
+                                     ((tmp & 0xf000) >> 12) |
+                                     ((tmp & 0x0800) >> 1));
+      *((uint16_t *)where + 1) = (uint16_t)((lower_insn & 0x8f00) |
+                                           ((tmp & 0x0700) << 4) |
+                                           (tmp & 0x00ff));
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
+        printf ("rtl: THM_MOVT_ABS/THM_MOVW_ABS_NC %p @ %p in %s\n",
+                (void *)*where, where, rtems_rtl_obj_oname (obj));
+      }
+
+      break;
+
+    case R_TYPE(THM_JUMP24):
+      /* same to THM_CALL; insn b.w */
+    case R_TYPE(THM_CALL):
+      upper_insn = *(uint16_t *)where;
+      lower_insn = *((uint16_t *)where + 1);
+      sign = (upper_insn & (1 << 10)) >> 10;
+      i1 = ((lower_insn >> 13) & 1) ^ sign ? 0 : 1;
+      i2 = ((lower_insn >> 11) & 1) ^ sign ? 0 : 1;
+      tmp = (i1 << 23) | (i2 << 22) | ((upper_insn & 0x3ff) << 12) | ((lower_insn & 0x7ff) << 1);
+      addend = (tmp | ((sign ? 0 : 1) << 24)) - (1 << 24);
+
+      if (isThumb(symvalue)) ;/*Thumb to Thumb call, nothing to care */
+      else {
+        if (ELF_R_TYPE(rel->r_info) == R_TYPE(THM_JUMP24)) {
+          tmp = (tmp + 2) & ~3; /* aligned to 4 bytes only for JUMP24 */
+          printf("THM_JUMP24 to arm not supported\n");
+          return false;
+        }
+        else {
+          /* THM_CALL bl-->blx */
+          lower_insn &=~(1<<12);
+        }
+      }
+
+      tmp = symvalue + addend;
+      tmp = tmp - (Elf_Addr)where;
+
+      if (((Elf_Sword)tmp > 0x7fffff) || ((Elf_Sword)tmp < -0x800000)) {
+        printf("THM_CALL/JUMP24 overflow\n");
+        return false;
+      }
+
+      sign = (tmp >> 24) & 1;
+      *(uint16_t *)where = (uint16_t)((upper_insn & 0xf800) | (sign << 10) |
+                                     ((tmp >> 12) & 0x3ff));
+
+      *((uint16_t *)where + 1) = (uint16_t)((lower_insn & 0xd000)|
+                                           ((sign ^ (~(tmp >> 23) & 1)) << 13) |
+                                           ((sign ^ (~(tmp >> 22) & 1)) << 11) |
+                                           ((tmp >> 1) & 0x7ff));
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)){
+        printf ("rtl: THM_CALL/JUMP24 %p @ %p in %s\n",
+                (void *)*where, where, rtems_rtl_obj_oname (obj));
+      }
+
+      break;
+
+    case R_TYPE(THM_JUMP19):
+
+      if (!isThumb(symvalue)) {
+        printf("THM_JUMP19 to arm not supported\n");
+        return false;
+      }
+
+      upper_insn = *(uint16_t *)where;
+      lower_insn = *((uint16_t *)where + 1);
+      sign = (upper_insn >> 10) & 0x1;
+
+      if ((((upper_insn & 0x3f) >> 7) & 0x7) == 0x7) {
+        printf("THM_JUMP19 failed\n");
+        return false; /*if cond <3:1> == '111', see Related codings in armv7a manual */
+      }
+
+      i1 = (lower_insn >> 13) & 0x1;
+      i2 = (lower_insn >> 11) & 0x1;
+
+      tmp = ((i2 << 19) | (i1 << 18) | ((upper_insn & 0x3f) << 12) | ((lower_insn & 0x7ff) << 1));
+      addend = (tmp | ((sign ? 0 : 1) << 20)) - (1 << 20);
+      tmp = symvalue + addend;
+
+      tmp = tmp - (Elf_Addr)where;
+
+      if (((Elf_Sword)tmp > 0x7ffffe) || ((Elf_Sword)tmp < -0x800000)) {
+        rtems_rtl_set_error (EINVAL, "%s: Overflow %ld "
+                             "THM_JUMP19 relocations",
+                             sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
+        return false;
+      }
+
+      sign = (tmp >> 20) & 0x1;
+      i2 = (tmp >> 19) & 0x1;
+      i1 = (tmp >> 18) & 0x1;
+
+      *(uint16_t*)where = (upper_insn & 0xfbc0) | (sign << 10) | ((tmp >> 12) & 0x3f);
+      *((uint16_t*)where + 1) = (lower_insn & 0xd000) | (i1 << 13) |
+                                (i2 << 11) | ((tmp >> 1) & 0x7ff);
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: THM_JUMP19 %p @ %p in %s\n",
+                (void *)*where, where, rtems_rtl_obj_oname (obj));
+      break;
+
+		default:
+      printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
+              "contents = %p\n",
+              ELF_R_SYM(rel->r_info), (uint32_t) ELF_R_TYPE(rel->r_info),
+              (void *)rel->r_offset, (void *)*where);
+      rtems_rtl_set_error (EINVAL,
+                           "%s: Unsupported relocation type %ld "
+                           "in non-PLT relocations",
+                           sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
+			return false;
+  }
+
+	return true;
+}
+
diff --git a/cpukit/libdl/rtl-mdreloc-bfin.c b/cpukit/libdl/rtl-mdreloc-bfin.c
new file mode 100644
index 0000000..1c9fd5b
--- /dev/null
+++ b/cpukit/libdl/rtl-mdreloc-bfin.c
@@ -0,0 +1,115 @@
+#include <sys/cdefs.h>
+
+#include <stdio.h>
+#include <rtl.h>
+#include <errno.h>
+#include "rtl-elf.h"
+#include "rtl-error.h"
+#include "rtl-trace.h"
+
+bool
+rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
+{
+  return true;
+}
+
+static inline Elf_Addr
+load_ptr(void *where)
+{
+	Elf_Addr res;
+
+	memcpy(&res, where, sizeof(res));
+
+	return (res);
+}
+
+bool
+rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t*      obj,
+                             const Elf_Rela*             rela,
+                             const rtems_rtl_obj_sect_t* sect,
+                             const char*                 symname,
+                             const Elf_Byte              syminfo,
+                             const Elf_Word              symvalue)
+{
+  Elf_Addr	target = 0;
+  Elf_Addr	*where;
+  Elf_Word	tmp;
+  Elf_Word	size; //byte
+
+  where = (Elf_Addr *)(sect->base + rela->r_offset);
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
+      printf("rela relocation type is %d relocated address 0x%08x",
+              ELF_R_TYPE(rela->r_info), where);
+  }
+
+  tmp = symvalue;
+  switch (ELF_R_TYPE(rela->r_info)) {
+    case R_TYPE(UNUSED0):
+      break;
+
+    case R_TYPE(HUIMM16):
+      tmp = symvalue >> 16;
+    case R_TYPE(LUIMM16):
+    case R_TYPE(RIMM16):
+      size = 2;
+      break;
+
+    case R_TYPE(BYTE4_DATA):
+      size = 4;
+      break;
+
+    case R_TYPE(PCREL24):
+    case R_TYPE(PCREL24_JU):
+      where = (Elf_Addr*)((Elf_Addr)where - 2); /* Back 2 bytes */
+      tmp = symvalue - (Elf_Addr)where;
+      tmp >>= 1;
+      if ((tmp & 0x20000000) == 0x20000000)
+        tmp |= 0xc0000000;
+
+      if ((tmp & 0xff000000) && (~tmp & 0xff800000)) {
+        printf("PCREL24/PCREL24_JU Overflow\n");
+        return false;
+      }
+
+      tmp = (load_ptr(where) & 0x0000ff00) | ((tmp & 0x0000ffff) << 16) |
+             ((tmp & 0x00ff0000) >> 16);
+      size = 4;
+      break;
+
+    case R_TYPE(PCREL12_JUMP_S):
+      tmp = symvalue - (Elf_Addr)where;
+      tmp >>= 1;
+      if ((tmp & 0x20000000) == 0x20000000)
+        tmp |= 0xc0000000;
+
+      if ((tmp & 0xfffff000) && (~tmp & 0xfffff800)) {
+        printf("PCREL12_JUMP_S Overflow\n");
+        return false;
+      }
+
+      tmp = ((*(uint16_t *)where) & 0xf000) | (tmp & 0xfff);
+      size = 2;
+      break;
+
+    default:
+      printf("Unspported rela type\n");
+      return false;
+  }
+
+  memcpy((void*)where, &tmp, size);
+
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t*      obj,
+                            const Elf_Rel*              rel,
+                            const rtems_rtl_obj_sect_t* sect,
+                            const char*                 symname,
+                            const Elf_Byte              syminfo,
+                            const Elf_Word              symvalue)
+{
+  rtems_rtl_set_error (EINVAL, "rel type record not supported");
+  return false;
+}
diff --git a/cpukit/libdl/rtl-mdreloc-h8300.c b/cpukit/libdl/rtl-mdreloc-h8300.c
new file mode 100644
index 0000000..925601b
--- /dev/null
+++ b/cpukit/libdl/rtl-mdreloc-h8300.c
@@ -0,0 +1,101 @@
+#include <sys/cdefs.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-elf.h"
+#include "rtl-error.h"
+#include "rtl-trace.h"
+
+bool
+rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
+{
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t*      obj,
+                             const Elf_Rela*             rela,
+                             const rtems_rtl_obj_sect_t* sect,
+                             const char*                 symname,
+                             const Elf_Byte              syminfo,
+                             const Elf_Word              symvalue)
+{
+  Elf_Addr	*where;
+  Elf_Word	tmp;
+
+  where = (Elf_Addr *)(sect->base + rela->r_offset);
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
+      printf("rela relocation type is %ld\n", ELF_R_TYPE(rela->r_info));
+      printf("relocated address 0x%08lx\n", (Elf_Addr)where);
+  }
+
+  tmp = symvalue;
+  switch (ELF_R_TYPE(rela->r_info)) {
+    case R_TYPE(NONE):
+      break;
+
+    case R_TYPE(DIR16):
+      *(uint16_t *)where += symvalue + rela->r_addend;
+      break;
+
+    case R_TYPE(DIR32):
+    case R_TYPE(DIR32A16):
+      *where += symvalue + rela->r_addend;
+      break;
+
+    case R_TYPE(DIR24A8):
+      if (ELF32_R_SYM(rela->r_info))
+        *where += symvalue + rela->r_addend;
+      break;
+
+    case R_TYPE(DIR24R8):
+      where = (uint32_t *)((uint32_t)where - 1);
+      *where = (*where & 0xff000000) | ((*where & 0xffffff) + symvalue + rela->r_addend);
+      break;
+
+    case R_TYPE(PCREL8):
+      /* bcc instruction */
+      tmp = symvalue + rela->r_addend - (Elf_Addr)where - 1;
+      if (((Elf32_Sword)tmp > 0x7f) || ((Elf32_Sword)tmp < -(Elf32_Sword)0x80)){
+        printf("PCREL8 overflow\n");
+          return false;
+      } else {
+        *(uint8_t *)where = tmp;
+      }
+      break;
+
+    case R_TYPE(PCREL16):
+      /* bcc instruction */
+      tmp = symvalue + rela->r_addend - (Elf_Addr)where - 2;
+      if (((Elf32_Sword)tmp > 0x7fff) || ((Elf32_Sword)tmp < -(Elf32_Sword)0x8000)){
+        printf("PCREL16 overflow\n");
+       return false;
+      } else {
+       *(uint16_t *)where = tmp;
+      }
+      break;
+
+    default:
+      rtems_rtl_set_error (EINVAL, "rela type record not supported");
+      printf("Unsupported reloc types\n");
+      return false;
+  }
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t*      obj,
+                            const Elf_Rel*              rel,
+                            const rtems_rtl_obj_sect_t* sect,
+                            const char*                 symname,
+                            const Elf_Byte              syminfo,
+                            const Elf_Word              symvalue)
+{
+  rtems_rtl_set_error (EINVAL, "rel type record not supported");
+  return false;
+}
diff --git a/cpukit/libdl/rtl-mdreloc-i386.c b/cpukit/libdl/rtl-mdreloc-i386.c
new file mode 100644
index 0000000..b6dd9b7
--- /dev/null
+++ b/cpukit/libdl/rtl-mdreloc-i386.c
@@ -0,0 +1,103 @@
+/*
+ * Taken from NetBSD and stripped of the relocations not needed on RTEMS.
+ */
+
+/*  $NetBSD: mdreloc.c,v 1.31 2010/01/14 11:58:32 skrll Exp $  */
+
+#include <sys/cdefs.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-elf.h"
+#include "rtl-error.h"
+#include "rtl-trace.h"
+
+bool
+rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
+{
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t*      obj,
+                             const Elf_Rela*             rel,
+                             const rtems_rtl_obj_sect_t* sect,
+                             const char*                 symname,
+                             const Elf_Byte              syminfo,
+                             const Elf_Word              symvalue)
+{
+  rtems_rtl_set_error (EINVAL, "rela type record not supported");
+  return false;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t*      obj,
+                            const Elf_Rel*              rel,
+                            const rtems_rtl_obj_sect_t* sect,
+                            const char*                 symname,
+                            const Elf_Byte              syminfo,
+                            const Elf_Word              symvalue)
+{
+	Elf_Addr  target = 0;
+  Elf_Addr* where;
+  Elf_Addr  tmp;
+
+  where = (Elf_Addr *)(sect->base + rel->r_offset);
+
+  switch (ELF_R_TYPE(rel->r_info)) {
+    case R_TYPE(NONE):
+      break;
+
+    case R_TYPE(PC32):
+      target = (Elf_Addr) symvalue;
+      *where += target - (Elf_Addr)where;
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: reloc PC32 in %s --> %p (%p @ %p) in %s\n",
+                sect->name, (void*) symvalue,
+                (void *)*where, where, rtems_rtl_obj_oname (obj));
+      break;
+
+    case R_TYPE(GOT32):
+    case R_TYPE(32):
+    case R_TYPE(GLOB_DAT):
+      target = (Elf_Addr) symvalue;
+
+      tmp = target + *where;
+      if (*where != tmp)
+        *where = tmp;
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: reloc 32/GLOB_DAT in %s --> %p @ %p in %s\n",
+                sect->name, (void *)*where, where,
+                rtems_rtl_obj_oname (obj));
+      break;
+
+    case R_TYPE(RELATIVE):
+      *where += (Elf_Addr)sect->base;
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: reloc RELATIVE in %s --> %p @ %p\n",
+                rtems_rtl_obj_oname (obj), (void *)*where, where);
+      break;
+
+    case R_TYPE(COPY):
+      printf ("rtl: reloc COPY (please report)\n");
+      break;
+
+    default:
+      printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
+              "contents = %p\n",
+              ELF_R_SYM(rel->r_info), (uint32_t) ELF_R_TYPE(rel->r_info),
+              (void *)rel->r_offset, (void *)*where);
+      rtems_rtl_set_error (EINVAL,
+                           "%s: Unsupported relocation type %ld "
+                           "in non-PLT relocations",
+                           sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
+      return false;
+  }
+
+  return true;
+}
diff --git a/cpukit/libdl/rtl-mdreloc-lm32.c b/cpukit/libdl/rtl-mdreloc-lm32.c
new file mode 100644
index 0000000..057d6ce
--- /dev/null
+++ b/cpukit/libdl/rtl-mdreloc-lm32.c
@@ -0,0 +1,120 @@
+#include <sys/cdefs.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-elf.h"
+#include "rtl-error.h"
+#include "rtl-trace.h"
+
+bool
+rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
+{
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t*      obj,
+                             const Elf_Rela*             rela,
+                             const rtems_rtl_obj_sect_t* sect,
+                             const char*                 symname,
+                             const Elf_Byte              syminfo,
+                             const Elf_Word              symvalue)
+{
+  Elf_Addr *where;
+  Elf32_Word tmp;
+  Elf32_Word insn;
+
+
+  where = (Elf_Addr *)(sect->base + rela->r_offset);
+
+  switch (ELF_R_TYPE(rela->r_info)) {
+    case R_TYPE(NONE):
+      break;
+
+    case R_TYPE(HI16):
+      insn = *where;
+      /* orhi/mvhi instruction
+       *  31--------26|25-21|20-16|15----0|
+       * |0 1 1 1 1 0 |rY   |rX   |imm16  |
+       */
+      if (0x1e == (insn >> 26)) {
+        insn &= 0xffff0000;
+        insn |= ((symvalue + rela->r_addend) >> 16);
+        *where = insn;
+      }
+      break;
+
+    case R_TYPE(LO16):
+      insn = *where;
+      /* ori instruction
+       *  31--------26|25-21|20-16|15----0|
+       * |0 0 1 1 1 0 |rY   |rX   |imm16  |
+       */
+      if (0xe == (insn >> 26)) {
+        insn &= 0xffff0000;
+        insn |= ((symvalue + rela->r_addend) & 0xffff);
+        *where = insn;
+      }
+      break;
+
+    case R_TYPE(CALL):
+      insn = *where;
+      /*
+       * calli instruction
+       *  31-------26|25---0|
+       * |1 1 1 1 1 0|imm26 |
+       * Syntax: call imm26
+       * Operation: ra = pc + 4; pc = pc + sign_extend(imm26<<2)
+       */
+      if (0x3e == (insn >> 26)) {
+        Elf_Sword imm26 = symvalue +rela->r_addend - (Elf_Addr)where;
+        imm26 = (imm26 >> 2) & 0x3ffffff;
+        insn = 0xf8000000 + imm26;
+        *where = insn;
+      }
+      break;
+
+    case R_TYPE(BRANCH):
+      insn = *where;
+      tmp = symvalue + rela->r_addend - (Elf_Addr)where;
+      tmp = (Elf32_Sword)tmp >> 2;
+      if (((Elf32_Sword)tmp > 0x7fff) || ((Elf32_Sword)tmp < -0x8000)){
+        printf("BRANCH Overflow\n");
+        return false;
+      }
+
+      *where = (*where & 0xffff0000) | (tmp & 0xffff);
+      break;
+
+    case R_TYPE(32):
+      *where = symvalue + rela->r_addend;
+      break;
+
+    default:
+      rtems_rtl_set_error (EINVAL, "rela type record not supported");
+      printf("Unsupported reloc types\n");
+      return false;
+  }
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
+      printf("rela relocation type is %ld\n", ELF_R_TYPE(rela->r_info));
+      printf("relocated address 0x%08lx\n", (Elf_Addr)where);
+  }
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t*      obj,
+                            const Elf_Rel*              rel,
+                            const rtems_rtl_obj_sect_t* sect,
+                            const char*                 symname,
+                            const Elf_Byte              syminfo,
+                            const Elf_Word              symvalue)
+{
+  rtems_rtl_set_error (EINVAL, "rela type record not supported");
+  return false;
+}
diff --git a/cpukit/libdl/rtl-mdreloc-m32r.c b/cpukit/libdl/rtl-mdreloc-m32r.c
new file mode 100644
index 0000000..de32f06
--- /dev/null
+++ b/cpukit/libdl/rtl-mdreloc-m32r.c
@@ -0,0 +1,156 @@
+#include <sys/cdefs.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-elf.h"
+#include "rtl-error.h"
+#include "rtl-trace.h"
+
+static inline Elf_Addr
+load_ptr(void *where)
+{
+  Elf_Addr res;
+
+  memcpy(&res, where, sizeof(res));
+
+  return (res);
+}
+
+static inline void
+store_ptr(void *where, Elf_Addr val)
+{
+	memcpy(where, &val, sizeof(val));
+}
+
+bool
+rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
+{
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t*      obj,
+                             const Elf_Rela*             rela,
+                             const rtems_rtl_obj_sect_t* sect,
+                             const char*                 symname,
+                             const Elf_Byte              syminfo,
+                             const Elf_Word              symvalue)
+{
+
+  Elf_Addr *where;
+  Elf_Word  tmp;
+
+  where = (Elf_Addr *)(sect->base + rela->r_offset);
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
+      printf("relocated address 0x%08lx\n", (Elf_Addr)where);
+  }
+
+  switch (ELF_R_TYPE(rela->r_info)) {
+    case R_TYPE(NONE):
+      break;
+
+    case R_TYPE(16_RELA):
+      /*
+       * half16: S + A
+       */
+      *(uint16_t *)where = (symvalue + rela->r_addend) & 0xffff;
+      break;
+
+    case R_TYPE(24_RELA):
+      /*
+       * imm24: (S + A) & 0xFFFFFF
+       */
+      tmp = symvalue + rela->r_addend;
+      if (((Elf_Sword)tmp > 0x7fffff) || ((Elf_Sword)tmp < -0x800000)) {
+        printf("24_RELA Overflow\n");
+        return false;
+      }
+      *where = (*where & 0xff000000) | tmp & 0xffffff;
+      break;
+
+    case R_TYPE(32_RELA):
+      /*
+       * word32: S + A
+       */
+      *where += symvalue + rela->r_addend;
+      break;
+
+    case R_TYPE(26_PCREL_RELA):
+      /*
+       * disp24: ((S + A - P) >> 2) & 0xFFFFFF
+       */
+      tmp = symvalue + rela->r_addend - (Elf_Addr)where;
+      tmp = (Elf_Sword)tmp >> 2;
+      if (((Elf_Sword)tmp > 0x7fffff) || ((Elf_Sword)tmp < -0x800000)) {
+        printf("26_PCREL_RELA Overflow\n");
+        return false;
+      }
+
+      *where = (*where & 0xff000000) | (tmp & 0xffffff);
+      break;
+
+    case R_TYPE(18_PCREL_RELA):
+      /*
+       * disp16: ((S + A - P) >> 2) & 0xFFFFFF
+       */
+      tmp = symvalue + rela->r_addend - (Elf_Addr)where;
+      tmp = (Elf_Sword)tmp >> 2;
+      if (((Elf_Sword)tmp > 0x7fff) || ((Elf_Sword)tmp < -0x8000)) {
+        printf("18_PCREL_RELA Overflow\n");
+        return false;
+      }
+
+      *where = (*where & 0xffff0000) | (tmp & 0xffff);
+      break;
+
+    case R_TYPE(HI16_ULO_RELA):
+      /*
+       * imm16: ((S + A) >> 16)
+       */
+      tmp = *where;
+      tmp += ((symvalue + rela->r_addend) >> 16) & 0xffff;
+      *where = tmp;
+      break;
+
+    case R_TYPE(HI16_SLO_RELA):
+      /*
+       * imm16: ((S + A) >> 16) or ((S + A + 0x10000) >> 16)
+       */
+      tmp = symvalue + rela->r_addend;
+      if (tmp & 0x8000) tmp += 0x10000;
+      tmp = (tmp >> 16) & 0xffff;
+      *where += tmp;
+      break;
+
+    case R_TYPE(LO16_RELA):
+      /*
+       * imm16: (S + A) & 0xFFFF
+       */
+      tmp = symvalue + rela->r_addend;
+      *where = (*where & 0xffff0000) | (tmp & 0xffff);
+      break;
+
+    default:
+      rtems_rtl_set_error (EINVAL, "rela type record not supported");
+      printf("Unsupported rela reloc types\n");
+      return false;
+  }
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t*      obj,
+                            const Elf_Rel*              rel,
+                            const rtems_rtl_obj_sect_t* sect,
+                            const char*                 symname,
+                            const Elf_Byte              syminfo,
+                            const Elf_Word              symvalue)
+{
+
+  rtems_rtl_set_error (EINVAL, "rel type record not supported");
+  return true;
+}
diff --git a/cpukit/libdl/rtl-mdreloc-m68k.c b/cpukit/libdl/rtl-mdreloc-m68k.c
new file mode 100644
index 0000000..36692eb
--- /dev/null
+++ b/cpukit/libdl/rtl-mdreloc-m68k.c
@@ -0,0 +1,148 @@
+/*
+ * Taken from NetBSD and stripped of the relocations not needed on RTEMS.
+ */
+
+/*	$NetBSD: mdreloc.c,v 1.26 2010/01/14 11:58:32 skrll Exp $	*/
+
+#include <sys/cdefs.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-elf.h"
+#include "rtl-error.h"
+#include "rtl-trace.h"
+
+static inline int overflow_8_check(int value)
+{
+  if ((value & 0xffffff00) && (~value & 0xffffff80))
+    return true;
+  return false;
+}
+
+static inline int overflow_16_check(int value)
+{
+  if ((value & 0xffff0000) && (~value & 0xffff8000))
+    return true;
+  return false;
+}
+
+bool
+rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
+{
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t*      obj,
+                             const Elf_Rela*             rela,
+                             const rtems_rtl_obj_sect_t* sect,
+                             const char*                 symnane,
+                             const Elf_Byte              syminfo,
+                             const Elf_Word              symvalue)
+{
+	Elf_Addr  target = 0;
+  Elf_Addr* where;
+  Elf_Word  tmp;
+
+  where = (Elf_Addr *)(sect->base + rela->r_offset);
+
+  switch (ELF_R_TYPE(rela->r_info)) {
+		case R_TYPE(NONE):
+			break;
+
+    case R_TYPE(PC8):
+      tmp = symvalue + rela->r_addend - (Elf_Addr)where;
+      if (overflow_8_check(tmp))
+        return false;
+
+      *(uint8_t *)where = tmp;
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: reloc R_TYPE_8/PC8 in %s --> %p (%p) in %s\n",
+                sect->name, (void*) (symvalue + rela->r_addend),
+                (void *)*where, rtems_rtl_obj_oname (obj));
+      break;
+
+    case R_TYPE(PC16):
+      tmp = symvalue + rela->r_addend - (Elf_Addr)where;
+      if (overflow_16_check(tmp))
+        return false;
+
+      *(uint16_t*)where = tmp;
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: reloc R_TYPE_16/PC16 in %s --> %p (%p) in %s\n",
+                sect->name, (void*) (symvalue + rela->r_addend),
+                (void *)*where, rtems_rtl_obj_oname (obj));
+      break;
+		case R_TYPE(PC32):
+      target = (Elf_Addr) symvalue + rela->r_addend;
+      *where += target - (Elf_Addr)where;
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: reloc PC32 in %s --> %p (%p) in %s\n",
+                sect->name, (void*) (symvalue + rela->r_addend),
+                (void *)*where, rtems_rtl_obj_oname (obj));
+      break;
+
+		case R_TYPE(GOT32):
+		case R_TYPE(32):
+		case R_TYPE(GLOB_DAT):
+      target = (Elf_Addr) symvalue + rela->r_addend;
+
+			if (*where != target)
+				*where = target;
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: reloc 32/GLOB_DAT in %s --> %p in %s\n",
+                sect->name, (void *)*where,
+                rtems_rtl_obj_oname (obj));
+			break;
+
+		case R_TYPE(RELATIVE):
+			*where += (Elf_Addr) sect->base + rela->r_addend;
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: reloc RELATIVE in %s --> %p\n",
+                rtems_rtl_obj_oname (obj), (void *)*where);
+			break;
+
+		case R_TYPE(COPY):
+			/*
+			 * These are deferred until all other relocations have
+			 * been done.  All we do here is make sure that the
+			 * COPY relocation is not in a shared library.  They
+			 * are allowed only in executable files.
+			 */
+      printf ("rtl: reloc COPY (please report)\n");
+			break;
+
+		default:
+      printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
+              "contents = %p\n",
+              ELF_R_SYM(rela->r_info), (uint32_t) ELF_R_TYPE(rela->r_info),
+              (void *)rela->r_offset, (void *)*where);
+      rtems_rtl_set_error (EINVAL,
+                           "%s: Unsupported relocation type %ld "
+                           "in non-PLT relocations",
+                           sect->name, (uint32_t) ELF_R_TYPE(rela->r_info));
+      return false;
+  }
+
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t*      obj,
+                            const Elf_Rel*              rel,
+                            const rtems_rtl_obj_sect_t* sect,
+                            const char*                 symname,
+                            const Elf_Byte              syminfo,
+                            const Elf_Word              symvalue)
+{
+  rtems_rtl_set_error (EINVAL, "rel type record not supported");
+  return false;
+}
diff --git a/cpukit/libdl/rtl-mdreloc-mips.c b/cpukit/libdl/rtl-mdreloc-mips.c
new file mode 100644
index 0000000..ea9989a
--- /dev/null
+++ b/cpukit/libdl/rtl-mdreloc-mips.c
@@ -0,0 +1,190 @@
+#include <sys/cdefs.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-elf.h"
+#include "rtl-error.h"
+#include "rtl-trace.h"
+
+bool
+rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
+{
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t*      obj,
+                             const Elf_Rela*             rela,
+                             const rtems_rtl_obj_sect_t* sect,
+                             const char*                 symname,
+                             const Elf_Byte              syminfo,
+                             const Elf_Word              symvalue)
+{
+  rtems_rtl_set_error (EINVAL, "rela type record not supported");
+  return false;
+}
+
+/*
+ * 1. _gp_disp symbol are not considered in this file.
+ * 2. There is a local/external column;
+ * local corresponds to (STB_LOCAL & STT_SECTION) and
+ * all others are external. Because if the type of a
+ * symbol is STT_SECTION, it must be STB_LOCAL. Thus
+ * just consider symtype here.
+ */
+bool
+rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t*      obj,
+                            const Elf_Rel*              rel,
+                            const rtems_rtl_obj_sect_t* sect,
+                            const char*                 symname,
+                            const Elf_Byte              syminfo,
+                            const Elf_Word              symvalue)
+{
+  Elf_Addr *where;
+  Elf_Word  tmp;
+  Elf_Word addend = (Elf_Word)0;
+  Elf_Word local = 0;
+  uint32_t t;
+
+
+  static Elf_Addr *where_hi16;
+  static Elf_Addr ahl;
+
+  where = (Elf_Addr *)(sect->base + rel->r_offset);
+  addend = *where;
+
+  if (syminfo == STT_SECTION)
+    local = 1;
+
+  switch (ELF_R_TYPE(rel->r_info)) {
+    case R_TYPE(NONE):
+      break;
+
+    case R_TYPE(16):
+      tmp = addend & 0xffff;
+      if ((tmp & 0x8000) == 0x8000)
+        tmp |= 0xffff0000; /* Sign extend */
+      tmp = symvalue + (int)tmp;
+      if ((tmp & 0xffff0000) != 0) {
+        printf("R_MIPS_16 Overflow\n");
+        return false;
+      }
+
+      *where = (tmp & 0xffff) | (*where & 0xffff0000);
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: R_MIPS_16 %p @ %p in %s\n",
+                (void *)*(where), where, rtems_rtl_obj_oname (obj));
+      break;
+
+    case R_TYPE(32):
+      tmp = symvalue + addend;
+      if (addend != tmp)
+        *where = tmp;
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: R_MIPS_32 %p @ %p in %s\n",
+                (void *)*(where), where, rtems_rtl_obj_oname (obj));
+      break;
+
+    case R_TYPE(26):
+
+        addend &= 0x03ffffff;
+        addend <<= 2;
+
+      if (local == 1) { /* STB_LOCAL and STT_SECTION */
+        tmp = symvalue + (((Elf_Addr)where & 0xf0000000) | addend);
+        tmp >>= 2;
+
+      } else { /* external */
+
+        tmp = addend;
+
+        if ((tmp & 0x08000000) == 0x08000000)
+          tmp |= 0xf0000000; /* Sign extened */
+        tmp = ((int)tmp + symvalue) >> 2;
+
+      }
+
+      *where &= ~0x03ffffff;
+      *where |= tmp & 0x03ffffff;
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: R_MIPS_26 local=%d %p @ %p in %s\n",
+                local, (void *)*(where), where, rtems_rtl_obj_oname (obj));
+      break;
+
+    case R_TYPE(HI16):
+      ahl = addend << 16;
+      where_hi16 = where;
+
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: R_MIPS_HI16 %p @ %p in %s\n",
+                (void *)*(where), where, rtems_rtl_obj_oname (obj));
+      break;
+
+    case R_TYPE(LO16):
+      //ahl += (int16_t)addend;
+      t = ahl + (int16_t)addend;
+      tmp = symvalue;
+      if (tmp == 0)
+        return false;
+
+      addend &= 0xffff0000;
+      addend |= (uint16_t)(t + tmp);
+      *where = addend;
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf("*where %x where %x\n", *where, where);
+
+      addend = *where_hi16;
+      addend &= 0xffff0000;
+      addend |= ((t + tmp) - (int16_t)(t + tmp)) >> 16;
+      *where_hi16 = addend;
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf("*where_hi %x where_hi %x\n", *where_hi16, where_hi16);
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: R_MIPS_LO16 %p @ %p in %s\n",
+                (void *)*(where), where, rtems_rtl_obj_oname (obj));
+      break;
+
+    case R_TYPE(PC16):
+      tmp = addend & 0xffff;
+      if ((tmp & 0x8000) == 0x8000)
+        tmp |= 0xffff0000; /* Sign extend */
+      tmp = symvalue + ((int)tmp*4) - (Elf_Addr)where;
+      tmp = (Elf_Sword)tmp >> 2;
+      if (((Elf_Sword)tmp > 0x7fff) || ((Elf_Sword)tmp < -0x8000)) {
+        printf("R_MIPS_PC16 Overflow\n");
+        return false;
+      }
+
+      *where = (tmp & 0xffff) | (*where & 0xffff0000);
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: R_MIPS_PC16 %p @ %p in %s\n",
+                (void *)*(where), where, rtems_rtl_obj_oname (obj));
+
+      break;
+
+		default:
+     printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
+             "contents = %p\n",
+              ELF_R_SYM(rel->r_info), (uint32_t) ELF_R_TYPE(rel->r_info),
+              (void *)rel->r_offset, (void *)*where);
+     rtems_rtl_set_error (EINVAL,
+                          "%s: Unsupported relocation type %ld "
+                          "in non-PLT relocations",
+                          sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
+     return false;
+  }
+
+  return true;
+}
diff --git a/cpukit/libdl/rtl-mdreloc-moxie.c b/cpukit/libdl/rtl-mdreloc-moxie.c
new file mode 100644
index 0000000..284f68e
--- /dev/null
+++ b/cpukit/libdl/rtl-mdreloc-moxie.c
@@ -0,0 +1,88 @@
+
+#include <sys/cdefs.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-elf.h"
+#include "rtl-error.h"
+#include "rtl-trace.h"
+
+bool
+rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
+{
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t*      obj,
+                             const Elf_Rela*             rela,
+                             const rtems_rtl_obj_sect_t* sect,
+                             const char*                 symname,
+                             const Elf_Byte              syminfo,
+                             const Elf_Word              symvalue)
+{
+  Elf_Addr *where;
+  Elf_Sword tmp;
+
+  where = (Elf_Addr *)(sect->base + rela->r_offset);
+
+  /* Handle the not 4byte aligned address carefully */
+
+  switch (ELF_R_TYPE(rela->r_info)) {
+    case R_TYPE(NONE):
+      break;
+
+    case R_TYPE(32):
+      *(uint16_t *)where = ((symvalue + rela->r_addend) >> 16) & 0xffff;
+      *((uint16_t *)where + 1) = (symvalue + rela->r_addend) & 0xffff;
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
+          printf("*where 0x%04x%04x\n", *((uint16_t *)where + 1), *(uint16_t *)where);
+      }
+      break;
+
+    case R_TYPE(PCREL10):
+      /* beq, bge, bgeu, bgt, bgtu, ble, bleu, blt, bltu, bne */
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
+        printf("*where %x\n", *(uint16_t *)where);
+        printf("symvalue - where %x\n", (int)(symvalue - (Elf_Word)where));
+      }
+      tmp = (symvalue + rela->r_addend - ((Elf_Word)where + 2)); /* pc is the next instruction */
+      tmp = (Elf_Sword)tmp >> 1;
+      if (((Elf32_Sword)tmp > 0x1ff) || ((Elf32_Sword)tmp < -(Elf32_Sword)0x200)){
+        printf("Overflow for PCREL10: %d exceed -0x200:0x1ff\n", tmp);
+        return false;
+      }
+
+      *(uint16_t *)where = (*(uint16_t *)where & 0xfc00) | (tmp & 0x3ff);
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
+          printf("*where 0x%04x\n",  *(uint16_t *)where);
+      }
+
+      break;
+
+    default:
+      rtems_rtl_set_error (EINVAL, "rela type record not supported");
+      printf("Unsupported reloc types\n");
+      return false;
+  }
+
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t*      obj,
+                            const Elf_Rel*              rel,
+                            const rtems_rtl_obj_sect_t* sect,
+                            const char*                 symname,
+                            const Elf_Byte              syminfo,
+                            const Elf_Word              symvalue)
+{
+  rtems_rtl_set_error (EINVAL, "rel type record not supported");
+  return false;
+}
diff --git a/cpukit/libdl/rtl-mdreloc-nios2.c b/cpukit/libdl/rtl-mdreloc-nios2.c
new file mode 100644
index 0000000..4f63f07
--- /dev/null
+++ b/cpukit/libdl/rtl-mdreloc-nios2.c
@@ -0,0 +1,44 @@
+/*
+ * Taken from NetBSD and stripped of the relocations not needed on RTEMS.
+ */
+
+/*	$NetBSD: mdreloc.c,v 1.26 2010/01/14 11:58:32 skrll Exp $	*/
+
+#include <sys/cdefs.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-elf.h"
+#include "rtl-error.h"
+#include "rtl-trace.h"
+
+bool
+rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
+{
+  return true;
+}
+
+
+bool
+rtems_rtl_elf_relocate_rela (rtems_rtl_obj_t*      obj,
+                             const Elf_Rela*       rela,
+                             rtems_rtl_obj_sect_t* sect,
+                             Elf_Word              symvalue)
+{
+
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (rtems_rtl_obj_t*      obj,
+                            const Elf_Rel*        rel,
+                            rtems_rtl_obj_sect_t* sect,
+                            Elf_Word              symvalue)
+{
+  printf ("rtl: rel type record not supported; please report\n");
+  return false;
+}
diff --git a/cpukit/libdl/rtl-mdreloc-powerpc.c b/cpukit/libdl/rtl-mdreloc-powerpc.c
new file mode 100644
index 0000000..d1c0a4f
--- /dev/null
+++ b/cpukit/libdl/rtl-mdreloc-powerpc.c
@@ -0,0 +1,186 @@
+/*
+ * Taken from NetBSD and stripped of the relocations not needed on RTEMS.
+ */
+
+/*  $NetBSD: ppc_reloc.c,v 1.44 2010/01/13 20:17:22 christos Exp $  */
+
+#include <sys/cdefs.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-elf.h"
+#include "rtl-error.h"
+#include "rtl-trace.h"
+
+#define ha(x) ((((u_int32_t)(x) & 0x8000) ? \
+                 ((u_int32_t)(x) + 0x10000) : (u_int32_t)(x)) >> 16)
+#define l(x) ((u_int32_t)(x) & 0xffff)
+
+
+bool
+rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
+{
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t*      obj,
+                             const Elf_Rela*             rela,
+                             const rtems_rtl_obj_sect_t* sect,
+                             const char*                 symname,
+                             const Elf_Byte              syminfo,
+                             const Elf_Word              symvalue)
+{
+  Elf_Addr  target = 0;
+  Elf_Addr* where;
+  Elf_Word tmp;
+  uint32_t mask = 0;
+  uint32_t bits = 0;
+
+  where = (Elf_Addr *)(sect->base + rela->r_offset);
+  switch (ELF_R_TYPE(rela->r_info)) {
+    case R_TYPE(NONE):
+      break;
+
+    case R_TYPE(32):
+      /*
+       * value:1; Field: word32; Expression: S + A
+       */
+      *where = symvalue + rela->r_addend;
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: ADDR32 %p @ %p in %s\n",
+                (void *)*(where), where, rtems_rtl_obj_oname (obj));
+      break;
+
+    case R_TYPE(14):
+      /*
+       * value:7; Field: low14*; Expression: (S + A) >> 2
+       */
+    case R_TYPE(24):
+      /*
+       * value:2; Field: low24*; Expression: (S + A) >> 2
+       */
+      if (ELF_R_TYPE(rela->r_info) == R_TYPE(14)) {
+        bits = 14;
+        mask = 0xfffc;
+      } else {
+        bits = 24;
+        mask = 0x3fffffc;
+      }
+      tmp = (symvalue + rela->r_addend) >> 2;
+      if (tmp > (1<<bits -1 )) {
+        printf("Overflow ADDR14/ADDR24\n");
+        return false;
+      }
+      tmp = *where;
+      tmp &= ~mask;
+      tmp |= (symvalue + rela->r_addend) & mask;
+      *where = tmp;
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: ADDR14/ADDR24 %p @ %p in %s\n",
+                (void *)*where, where, rtems_rtl_obj_oname (obj));
+      break;
+
+    case R_TYPE(16_HA):
+      /*
+       * value:6; Field:half16; Expression: #ha(S+A)
+       */
+
+      tmp = symvalue + rela->r_addend;
+      *(uint16_t *)where = (((tmp >> 16) + ((tmp & 0x8000) ? 1: 0)) & 0xffff);
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: 16_HA %p @ %p in %s\n",
+                (void *)*(where), where, rtems_rtl_obj_oname (obj));
+      break;
+
+    case R_TYPE(16_HI):
+      /*
+       * value:5; Field:half16; Expression: #hi(S+A)
+       */
+      *(uint16_t *)where = ((symvalue + rela->r_addend) >> 16) & 0xffff;
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: 16_HI %p @ %p in %s\n",
+                (void *)*where, where, rtems_rtl_obj_oname (obj));
+      break;
+    case R_TYPE(16_LO):
+      /*
+       * value:4; Field:half16; Expression: #lo(S+A)
+       */
+      *(uint16_t *)where = (symvalue + (rela->r_addend)) & 0xffff;
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: 16_LO %p @ %p in %s\n",
+                (void *)*where, where, rtems_rtl_obj_oname (obj));
+      break;
+
+    case R_TYPE(REL14):
+      /*
+       * value:11; Field:low14*; Expression:(S+A-P)>>2
+       */
+    case R_TYPE(REL24):
+      /*
+       * value:10; Field:low24*; Expression:(S+A-P)>>2
+       */
+      if (ELF_R_TYPE(rela->r_info) == R_TYPE(REL24)) {
+        mask = 0x3fffffc;
+        bits = 24;
+      }
+      else if (ELF_R_TYPE(rela->r_info) == R_TYPE(REL14)) {
+        mask = 0xfffc;
+        bits = 14;
+      }
+
+      tmp =((int) (symvalue + rela->r_addend - (Elf_Addr)where)) >> 2;
+      if (((Elf_Sword)tmp > ((1<<(bits-1)) - 1)) ||
+          ((Elf_Sword)tmp < -(1<<(bits-1)))) {
+        printf("Overflow REL14/REL24\n");
+        return false;
+      }
+
+      tmp = *where;
+      tmp &= ~mask;
+      tmp |= (symvalue + rela->r_addend - (Elf_Addr)where) & mask;
+      *where = tmp;
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: REL24/REL14 %p @ %p in %s\n",
+                (void *)*where, where, rtems_rtl_obj_oname (obj));
+      break;
+
+    case R_TYPE(REL32):
+      /*
+       * value:26; Field:word32*; Expression:S+A-P
+       */
+      *where = symvalue + rela->r_addend - (Elf_Addr)where;
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: REL32 %p @ %p in %s\n",
+                (void *)*where, where, rtems_rtl_obj_oname (obj));
+      break;
+
+    default:
+      printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
+              "contents = %p\n",
+              ELF_R_SYM(rela->r_info), (uint32_t) ELF_R_TYPE(rela->r_info),
+              (void *)rela->r_offset, (void *)*where);
+      rtems_rtl_set_error (EINVAL,
+                           "%s: Unsupported relocation type %ld "
+                           "in non-PLT relocations",
+                           sect->name, (uint32_t) ELF_R_TYPE(rela->r_info));
+      return false;
+  }
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t*      obj,
+                            const Elf_Rel*              rel,
+                            const rtems_rtl_obj_sect_t* sect,
+                            const char*                 symname,
+                            const Elf_Byte              syminfo,
+                            const Elf_Word              symvalue)
+{
+  printf ("rtl: rel type record not supported; please report\n");
+  return false;
+}
diff --git a/cpukit/libdl/rtl-mdreloc-sparc.c b/cpukit/libdl/rtl-mdreloc-sparc.c
new file mode 100644
index 0000000..a8bf5e1
--- /dev/null
+++ b/cpukit/libdl/rtl-mdreloc-sparc.c
@@ -0,0 +1,261 @@
+/*
+ * Taken from NetBSD and stripped of the relocations not needed on RTEMS.
+ */
+
+/*  $NetBSD: mdreloc.c,v 1.43 2010/01/13 20:17:22 christos Exp $  */
+
+/*-
+ * Copyright (c) 1999, 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Paul Kranenburg and by Charles M. Hannum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <stdio.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-elf.h"
+#include "rtl-error.h"
+#include "rtl-trace.h"
+
+/*
+ * The following table holds for each relocation type:
+ *  - the width in bits of the memory location the relocation
+ *    applies to (not currently used)
+ *  - the number of bits the relocation value must be shifted to the
+ *    right (i.e. discard least significant bits) to fit into
+ *    the appropriate field in the instruction word.
+ *  - flags indicating whether
+ *    * the relocation involves a symbol
+ *    * the relocation is relative to the current position
+ *    * the relocation is for a GOT entry
+ *    * the relocation is relative to the load address
+ *
+ */
+#define _RF_S     0x80000000           /* Resolve symbol */
+#define _RF_A     0x40000000           /* Use addend */
+#define _RF_P     0x20000000           /* Location relative */
+#define _RF_G     0x10000000           /* GOT offset */
+#define _RF_B     0x08000000           /* Load address relative */
+#define _RF_U     0x04000000           /* Unaligned */
+#define _RF_SZ(s) (((s) & 0xff) << 8)  /* memory target size */
+#define _RF_RS(s) ( (s) & 0xff)        /* right shift */
+
+static const uint32_t reloc_target_flags[] = {
+  0,                                             /* NONE */
+  _RF_S|_RF_A|        _RF_SZ(8)  | _RF_RS(0),    /* RELOC_8 */
+  _RF_S|_RF_A|        _RF_SZ(16) | _RF_RS(0),    /* RELOC_16 */
+  _RF_S|_RF_A|        _RF_SZ(32) | _RF_RS(0),    /* RELOC_32 */
+  _RF_S|_RF_A|_RF_P|  _RF_SZ(8)  | _RF_RS(0),    /* DISP_8 */
+  _RF_S|_RF_A|_RF_P|  _RF_SZ(16) | _RF_RS(0),    /* DISP_16 */
+  _RF_S|_RF_A|_RF_P|  _RF_SZ(32) | _RF_RS(0),    /* DISP_32 */
+  _RF_S|_RF_A|_RF_P|  _RF_SZ(32) | _RF_RS(2),    /* WDISP_30 */
+  _RF_S|_RF_A|_RF_P|  _RF_SZ(32) | _RF_RS(2),    /* WDISP_22 */
+  _RF_S|_RF_A|        _RF_SZ(32) | _RF_RS(10),   /* HI22 */
+  _RF_S|_RF_A|        _RF_SZ(32) | _RF_RS(0),    /* 22 */
+  _RF_S|_RF_A|        _RF_SZ(32) | _RF_RS(0),    /* 13 */
+  _RF_S|_RF_A|        _RF_SZ(32) | _RF_RS(0),    /* LO10 */
+  _RF_G|              _RF_SZ(32) | _RF_RS(0),    /* GOT10 */
+  _RF_G|              _RF_SZ(32) | _RF_RS(0),    /* GOT13 */
+  _RF_G|              _RF_SZ(32) | _RF_RS(10),   /* GOT22 */
+  _RF_S|_RF_A|_RF_P|  _RF_SZ(32) | _RF_RS(0),    /* PC10 */
+  _RF_S|_RF_A|_RF_P|  _RF_SZ(32) | _RF_RS(10),   /* PC22 */
+        _RF_A|_RF_P|  _RF_SZ(32) | _RF_RS(2),    /* WPLT30 */
+                      _RF_SZ(32) | _RF_RS(0),    /* COPY */
+  _RF_S|_RF_A|        _RF_SZ(32) | _RF_RS(0),    /* GLOB_DAT */
+                      _RF_SZ(32) | _RF_RS(0),    /* JMP_SLOT */
+        _RF_A|  _RF_B|_RF_SZ(32) | _RF_RS(0),    /* RELATIVE */
+  _RF_S|_RF_A|  _RF_U|_RF_SZ(32) | _RF_RS(0),    /* UA_32 */
+};
+
+#define NOT_CURRENTLY_USED_BUT_MAYBE_USEFUL
+#ifdef NOT_CURRENTLY_USED_BUT_MAYBE_USEFUL
+static const char *reloc_names[] = {
+  "NONE", "RELOC_8", "RELOC_16", "RELOC_32", "DISP_8",
+  "DISP_16", "DISP_32", "WDISP_30", "WDISP_22", "HI22",
+  "22", "13", "LO10", "GOT10", "GOT13",
+  "GOT22", "PC10", "PC22", "WPLT30", "COPY",
+  "GLOB_DAT", "JMP_SLOT", "RELATIVE", "UA_32"
+};
+#endif
+
+#define RELOC_RESOLVE_SYMBOL(t)    ((reloc_target_flags[t] & _RF_S) != 0)
+#define RELOC_PC_RELATIVE(t)       ((reloc_target_flags[t] & _RF_P) != 0)
+#define RELOC_BASE_RELATIVE(t)     ((reloc_target_flags[t] & _RF_B) != 0)
+#define RELOC_UNALIGNED(t)         ((reloc_target_flags[t] & _RF_U) != 0)
+#define RELOC_USE_ADDEND(t)        ((reloc_target_flags[t] & _RF_A) != 0)
+#define RELOC_TARGET_SIZE(t)       ((reloc_target_flags[t] >> 8) & 0xff)
+#define RELOC_VALUE_RIGHTSHIFT(t)  (reloc_target_flags[t] & 0xff)
+
+static const int reloc_target_bitmask[] = {
+#define _BM(x)  (~(-(1ULL << (x))))
+  0,        /* NONE */
+  _BM(8),  _BM(16), _BM(32),  /* RELOC_8, _16, _32 */
+  _BM(8),  _BM(16), _BM(32),  /* DISP8, DISP16, DISP32 */
+  _BM(30), _BM(22),           /* WDISP30, WDISP22 */
+  _BM(22), _BM(22),           /* HI22, _22 */
+  _BM(13), _BM(10),           /* RELOC_13, _LO10 */
+  _BM(10), _BM(13), _BM(22),  /* GOT10, GOT13, GOT22 */
+  _BM(10), _BM(22),           /* _PC10, _PC22 */
+  _BM(30), 0,                 /* _WPLT30, _COPY */
+  -1, -1, -1,                 /* _GLOB_DAT, JMP_SLOT, _RELATIVE */
+  _BM(32)                     /* _UA32 */
+#undef _BM
+};
+#define RELOC_VALUE_BITMASK(t)  (reloc_target_bitmask[t])
+
+bool
+rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
+{
+  return RELOC_RESOLVE_SYMBOL (type) ? true : false;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t*      obj,
+                             const Elf_Rela*             rela,
+                             const rtems_rtl_obj_sect_t* sect,
+                             const char*                 symname,
+                             const Elf_Byte              syminfo,
+                             const Elf_Word              symvalue)
+{
+  Elf_Addr *where;
+  Elf_Word type, value, mask;
+
+  where = (Elf_Addr *) (sect->base + rela->r_offset);
+
+  type = ELF_R_TYPE(rela->r_info);
+  if (type == R_TYPE(NONE))
+    return true;
+
+  /* We do JMP_SLOTs in _rtld_bind() below */
+  if (type == R_TYPE(JMP_SLOT))
+    return true;
+
+  /* COPY relocs are also handled elsewhere */
+  if (type == R_TYPE(COPY))
+    return true;
+
+  /*
+   * We use the fact that relocation types are an `enum'
+   * Note: R_SPARC_6 is currently numerically largest.
+   */
+  if (type > R_TYPE(6))
+    return false;
+
+  value = rela->r_addend;
+
+  /*
+   * Handle relative relocs here, as an optimization.
+   */
+  if (type == R_TYPE (RELATIVE)) {
+    *where += (Elf_Addr)(sect->base + value);
+    if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+      printf ("rtl: reloc relative in %s --> %p",
+              rtems_rtl_obj_oname (obj), (void *)*where);
+    return true;
+  }
+
+  if (RELOC_RESOLVE_SYMBOL (type)) {
+    /* Add in the symbol's absolute address */
+    value += symvalue;
+  }
+
+  if (RELOC_PC_RELATIVE (type)) {
+    value -= (Elf_Word)where;
+  }
+
+  if (RELOC_BASE_RELATIVE (type)) {
+    /*
+     * Note that even though sparcs use `Elf_rela'
+     * exclusively we still need the implicit memory addend
+     * in relocations referring to GOT entries.
+     * Undoubtedly, someone f*cked this up in the distant
+     * past, and now we're stuck with it in the name of
+     * compatibility for all eternity..
+     *
+     * In any case, the implicit and explicit should be
+     * mutually exclusive. We provide a check for that
+     * here.
+     */
+#define DIAGNOSTIC
+#ifdef DIAGNOSTIC
+    if (value != 0 && *where != 0) {
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf("rtl: reloc base_rel(%s): where=%p, *where 0x%lx, "
+               "addend=0x%lx, base %p\n",
+               rtems_rtl_obj_oname (obj),
+               where, *where, rela->r_addend, sect->base);
+    }
+#endif
+    value += (Elf_Word)(sect->base + *where);
+  }
+
+  mask = RELOC_VALUE_BITMASK (type);
+  value >>= RELOC_VALUE_RIGHTSHIFT (type);
+  value &= mask;
+
+  if (RELOC_UNALIGNED(type)) {
+    /* Handle unaligned relocations. */
+    Elf_Addr tmp = 0;
+    char *ptr = (char *)where;
+    int i, size = RELOC_TARGET_SIZE (type) / 8;
+
+    /* Read it in one byte at a time. */
+    for (i=0; i<size; i++)
+      tmp = (tmp << 8) | ptr[i];
+
+    tmp &= ~mask;
+    tmp |= value;
+
+    /* Write it back out. */
+    for (i=0; i<size; i++)
+      ptr[i] = ((tmp >> (8*i)) & 0xff);
+
+  } else {
+    *where &= ~mask;
+    *where |= value;
+  }
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+    printf ("rtl: %s %p @ %p in %s\n",
+            reloc_names[type], (void *)*where, where, rtems_rtl_obj_oname (obj));
+
+
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t*      obj,
+                            const Elf_Rel*              rel,
+                            const rtems_rtl_obj_sect_t* sect,
+                            const char*                 symname,
+                            const Elf_Byte              syminfo,
+                            const Elf_Word              symvalue)
+{
+  printf ("rtl: rel type record not supported; please report\n");
+  return false;
+}
diff --git a/cpukit/libdl/rtl-mdreloc-v850.c b/cpukit/libdl/rtl-mdreloc-v850.c
new file mode 100644
index 0000000..5372e81
--- /dev/null
+++ b/cpukit/libdl/rtl-mdreloc-v850.c
@@ -0,0 +1,97 @@
+
+#include <sys/cdefs.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-elf.h"
+#include "rtl-error.h"
+#include "rtl-trace.h"
+
+bool
+rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
+{
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t*      obj,
+                             const Elf_Rela*             rela,
+                             const rtems_rtl_obj_sect_t* sect,
+                             const char*                 symname,
+                             const Elf_Byte              syminfo,
+                             const Elf_Word              symvalue)
+{
+  Elf_Addr *where;
+  Elf_Word tmp;
+
+  where = (Elf_Addr *)(sect->base + rela->r_offset);
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
+      printf("rela relocation type is %ld\n", ELF_R_TYPE(rela->r_info));
+      printf("relocated address 0x%08lx\n", (Elf_Addr)where);
+  }
+
+  switch (ELF_R_TYPE(rela->r_info)) {
+    case R_TYPE(NONE):
+      break;
+
+    case R_TYPE(HI16_S):
+      tmp = (Elf_Sword)(symvalue + rela->r_addend) >> 16;
+      ((uint16_t *)where)[0] = tmp & 0xffff;
+      break;
+
+    case R_TYPE(LO16):
+      tmp = symvalue + rela->r_addend;
+      ((uint16_t *)where)[0] = tmp & 0xffff;
+      break;
+
+    case R_TYPE(LO16_S1):
+      tmp = symvalue + rela->r_addend;
+      ((uint16_t *)where)[0] = tmp & 0xfffe | 0x1;
+      break;
+
+    case R_TYPE(22_PCREL):
+      tmp =  symvalue + rela->r_addend - (Elf_Addr)where;
+      if (((Elf_Sword)tmp > 0x1fffff) || ((Elf_Sword)tmp < -0x200000)) {
+        printf("Overflow\n");
+        return false;
+      }
+
+      ((uint16_t *)where)[0] = (*(uint16_t *)where & 0xffc0) |
+        ((tmp >> 16) & 0x3f);
+      ((uint16_t *)where)[1] = (tmp & 0xfffe);
+
+      break;
+
+    case R_TYPE(ABS32):
+      tmp = symvalue + rela->r_addend;
+      tmp += ((uint16_t *)where)[0];
+      tmp += ((uint16_t *)where)[1] << 16;
+      ((uint16_t *)where)[0] = tmp & 0xffff;
+      ((uint16_t *)where)[1] = (tmp >> 16) & 0xffff;
+      break;
+
+    default:
+      rtems_rtl_set_error (EINVAL, "rela type record not supported");
+      printf("error reloc type\n");
+      return false;
+  }
+
+  return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t*      obj,
+                            const Elf_Rel*              rel,
+                            const rtems_rtl_obj_sect_t* sect,
+                            const char*                 symname,
+                            const Elf_Byte              syminfo,
+                            const Elf_Word              symvalue)
+{
+  rtems_rtl_set_error (EINVAL, "rel type record not supported");
+  return false;
+}
diff --git a/cpukit/libdl/rtl-obj-cache.c b/cpukit/libdl/rtl-obj-cache.c
new file mode 100644
index 0000000..23d7d07
--- /dev/null
+++ b/cpukit/libdl/rtl-obj-cache.c
@@ -0,0 +1,197 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object File cache buffers a section of the
+ *        object file in a buffer to localise read performance.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <rtems/rtl/rtl-allocator.h>
+#include "rtl-obj-cache.h"
+#include "rtl-error.h"
+
+bool
+rtems_rtl_obj_cache_open (rtems_rtl_obj_cache_t* cache, size_t size)
+{
+  cache->fd        = -1;
+  cache->file_size = 0;
+  cache->offset    = 0;
+  cache->size      = size;
+  cache->level     = 0;
+  cache->buffer    = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT, size, false);
+  if (!cache->buffer)
+  {
+    rtems_rtl_set_error (ENOMEM, "no memory for cache buffer");
+    return false;
+  }
+  return true;
+}
+
+void
+rtems_rtl_obj_cache_close (rtems_rtl_obj_cache_t* cache)
+{
+  rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, cache->buffer);
+  cache->fd        = -1;
+  cache->file_size = 0;
+  cache->level     = 0;
+}
+
+void
+rtems_rtl_obj_cache_flush (rtems_rtl_obj_cache_t* cache)
+{
+  cache->fd        = -1;
+  cache->file_size = 0;
+  cache->level     = 0;
+}
+
+bool
+rtems_rtl_obj_cache_read (rtems_rtl_obj_cache_t* cache,
+                          int                    fd,
+                          off_t                  offset,
+                          void**                 buffer,
+                          size_t*                length)
+{
+  struct stat sb;
+
+  if (*length > cache->size)
+  {
+    rtems_rtl_set_error (EINVAL, "read size larger than cache size");
+    return false;
+  }
+
+  if (cache->fd == fd)
+  {
+    if (offset > cache->file_size)
+    {
+      rtems_rtl_set_error (EINVAL, "offset past end of file: offset=%i size=%i",
+                           (int) offset, (int) cache->file_size);
+      return false;
+    }
+
+    if ((offset + *length) > cache->file_size)
+      *length = cache->file_size - offset;
+  }
+
+  while (true)
+  {
+    size_t buffer_offset = 0;
+    size_t buffer_read = cache->size;
+
+    /*
+     * Is the data in the cache for this file ?
+     */
+    if (fd == cache->fd)
+    {
+      /*
+       * Is any part of the data in the cache ?
+       */
+      if ((offset >= cache->offset) &&
+          (offset < (cache->offset + cache->level)))
+      {
+        buffer_offset = offset - cache->offset;
+
+        /*
+         * Return the location of the data in the cache.
+         */
+        *buffer = cache->buffer + buffer_offset;
+
+        /*
+         * Is all the data in the cache or just a part ?
+         */
+        if (*length <= (cache->level - buffer_offset))
+        {
+          return true;
+        }
+
+        /*
+         * Copy down the data in the buffer and then fill the remaining
+         * space with as much data we are able to read.
+         */
+        memmove (cache->buffer,
+                 cache->buffer + buffer_offset,
+                 cache->size - buffer_offset);
+
+        buffer_read   = buffer_offset;
+        buffer_offset = cache->size - buffer_offset;
+      }
+    }
+
+    if (lseek (fd, offset + buffer_offset, SEEK_SET) < 0)
+    {
+      rtems_rtl_set_error (errno, "file seek failed");
+      return false;
+    }
+
+    /*
+     * Loop reading the data from the file until either an error or 0 is
+     * returned and if data has been read check if the amount is what we
+     * want. If not it is an error. A POSIX read can read data in fragments.
+     */
+    cache->level = buffer_read;
+    while (buffer_read)
+    {
+      int r = read (fd, cache->buffer + buffer_offset, buffer_read);
+      if (r < 0)
+      {
+        rtems_rtl_set_error (errno, "file read failed");
+        return false;
+      }
+      if ((r == 0) && buffer_read)
+      {
+        cache->level = cache->level - buffer_read;
+        buffer_read = 0;
+      }
+      else
+      {
+        buffer_read -= r;
+        buffer_offset += r;
+      }
+    }
+
+    cache->fd = fd;
+    cache->offset = offset;
+
+    if (fstat (cache->fd, &sb) < 0)
+    {
+      rtems_rtl_set_error (errno, "file stat failed");
+      return false;
+    }
+
+    cache->file_size = sb.st_size;
+  }
+
+  return false;
+}
+
+bool
+rtems_rtl_obj_cache_read_byval (rtems_rtl_obj_cache_t* cache,
+                                int                    fd,
+                                off_t                  offset,
+                                void*                  buffer,
+                                size_t                 length)
+{
+  void*  cbuffer = 0;
+  size_t len = length;
+  bool   ok = rtems_rtl_obj_cache_read (cache, fd, offset, &cbuffer, &len);
+  if (ok && (len != length))
+    ok = false;
+  if (ok)
+    memcpy (buffer, cbuffer, length);
+  return ok;
+}
diff --git a/cpukit/libdl/rtl-obj-cache.h b/cpukit/libdl/rtl-obj-cache.h
new file mode 100644
index 0000000..8abb7f3
--- /dev/null
+++ b/cpukit/libdl/rtl-obj-cache.h
@@ -0,0 +1,132 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object File cache buffers a section of the
+ *        object file in a buffer to localise read performance.
+ *
+ * This is a simple object file cache that holds a buffer of data from the
+ * offset in the file the read is requested from. Writes are not supported.
+ *
+ * The cache holds the file descriptor, the offset into the file and the amount
+ * of valid data in the cache. If the file is ever modified the user of the
+ * cache to responsible for flushing the cache. For example the cache should be
+ * flused if the file is closed.
+ *
+ * The cache can return by reference or by value. By reference allow access to
+ * the cache buffer. Do not modify the cache's data. By value will copy the
+ * requested data into the user supplied buffer.
+ *
+ * The read by reference call allows you to probe the file's data. For example
+ * a string in an object file can be an unknown length. You can request a read
+ * up to the cache's size by reference. The code will attempt to have this data
+ * in the buffer. If there is not enough data in the file the length will be
+ * modifed to reflect this.
+ *
+ * You can have more than one cache for a single file all looking at different
+ * parts of the file.
+ */
+
+#if !defined (_RTEMS_RTL_OBJ_CACHE_H_)
+#define _RTEMS_RTL_OBJ_CACHE_H_
+
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * The buffer cache.
+ */
+typedef struct rtems_rtl_obj_cache_s
+{
+  int      fd;        /**< The file descriptor of the data in the cache. */
+  size_t   file_size; /**< The size of the file. */
+  off_t    offset;    /**< The base offset of the buffer. */
+  size_t   size;      /**< The size of the cache. */
+  size_t   level;     /**< The amount of data in the cache. A file can be
+                       * smaller than the cache file. */
+  uint8_t* buffer;    /**< The buffer */
+} rtems_rtl_obj_cache_t;
+
+/**
+ * Open a cache allocating a single buffer of the size passed. The default
+ * state of the cache is flushed. No already open checks are made.
+ *
+ * @param cache The cache to initialise.
+ * @param size The size of the cache.
+ * @retval true The cache is open.
+ * @retval false The cache is not open. The RTL error is set.
+ */
+bool rtems_rtl_obj_cache_open (rtems_rtl_obj_cache_t* cache, size_t size);
+
+/**
+ * Close a cache.
+ *
+ * @param cache The cache to close.
+ */
+void rtems_rtl_obj_cache_close (rtems_rtl_obj_cache_t* cache);
+
+/**
+ * Flush the cache. Any further read will read the data from the file.
+ *
+ * @param cache The cache to flush.
+ */
+void rtems_rtl_obj_cache_flush (rtems_rtl_obj_cache_t* cache);
+
+/**
+ * Read data by reference. The length contains the amount of data that should
+ * be available in the cache and referenced by the buffer handle. It must be
+ * less than or equal to the size of the cache. This call will return the
+ * amount of data that is available. It can be less than you ask if the offset
+ * and size is past the end of the file.
+ *
+ * @param cache The cache to reference data from.
+ * @param fd The file descriptor. Must be an open file.
+ * @param offset The offset in the file to reference the data to.
+ * @param buffer The location to reference the data from.
+ * @param length The length of data to reference. Can be modified to a
+ *               lesser value and true is still returned so check it.
+ * @retval true The data referenced is in the cache.
+ * @retval false The read failed and the RTL error has been set.
+ */
+bool rtems_rtl_obj_cache_read (rtems_rtl_obj_cache_t* cache,
+                               int                    fd,
+                               off_t                  offset,
+                               void**                 buffer,
+                               size_t*                length);
+
+/**
+ * Read data by value. The data is copied to the user supplied buffer.
+ *
+ * @param cache The cache to read the data from.
+ * @param fd The file descriptor. Must be an open file.
+ * @param offset The offset in the file to read the data from.
+ * @param buffer The location the data is written into.
+ * @param length The length of data to read.
+ * @retval true The data has been read from the cache.
+ * @retval false The read failed and the RTL error has been set.
+ */
+bool rtems_rtl_obj_cache_read_byval (rtems_rtl_obj_cache_t* cache,
+                                     int                    fd,
+                                     off_t                  offset,
+                                     void*                  buffer,
+                                     size_t                 length);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/libdl/rtl-obj-comp.c b/cpukit/libdl/rtl-obj-comp.c
new file mode 100644
index 0000000..d9c5462
--- /dev/null
+++ b/cpukit/libdl/rtl-obj-comp.c
@@ -0,0 +1,179 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object Compression manages a compress
+ *        stream of data.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <rtems/rtl/rtl-allocator.h>
+#include "rtl-obj-comp.h"
+#include "rtl-error.h"
+
+#include "fastlz.h"
+
+#include <stdio.h>
+
+bool
+rtems_rtl_obj_comp_open (rtems_rtl_obj_comp_t*  comp,
+                         size_t                 size)
+{
+  comp->cache  = NULL;
+  comp->fd = -1;
+  comp->compression = RTEMS_RTL_COMP_LZ77;
+  comp->offset = 0;
+  comp->size   = size;
+  comp->level  = 0;
+  comp->buffer = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT, size, false);
+  if (!comp->buffer)
+  {
+    rtems_rtl_set_error (ENOMEM, "no memory for compressor buffer");
+    return false;
+  }
+  comp->read = 0;
+  return true;
+}
+
+void
+rtems_rtl_obj_comp_close (rtems_rtl_obj_comp_t* comp)
+{
+  rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, comp->buffer);
+  comp->cache = NULL;
+  comp->fd = -1;
+  comp->compression = RTEMS_RTL_COMP_LZ77;
+  comp->level = 0;
+  comp->size = 0;
+  comp->offset = 0;
+  comp->read = 0;
+}
+
+void
+rtems_rtl_obj_comp_set (rtems_rtl_obj_comp_t*  comp,
+                        rtems_rtl_obj_cache_t* cache,
+                        int                    fd,
+                        int                    compression,
+                        off_t                  offset)
+{
+  comp->cache = cache;
+  comp->fd = fd;
+  comp->compression = compression;
+  comp->offset = offset;
+  comp->level = 0;
+  comp->read = 0;
+}
+
+bool
+rtems_rtl_obj_comp_read (rtems_rtl_obj_comp_t* comp,
+                         void*                 buffer,
+                         size_t                length)
+{
+  uint8_t* bin = buffer;
+
+  if (!comp->cache)
+  {
+    rtems_rtl_set_error (EINVAL, "not open");
+    return false;
+  }
+
+  if (comp->fd != comp->cache->fd)
+  {
+    comp->level = 0;
+  }
+
+  while (length)
+  {
+    size_t buffer_level;
+
+    buffer_level = length > comp->level ? comp->level : length;
+
+    if (buffer_level)
+    {
+      memcpy (bin, comp->buffer, buffer_level);
+
+      if ((comp->level - buffer_level) != 0)
+      {
+        memmove (comp->buffer,
+                 comp->buffer + buffer_level,
+                 comp->level - buffer_level);
+      }
+
+      bin += buffer_level;
+      length -= buffer_level;
+      comp->level -= buffer_level;
+      comp->read += buffer_level;
+    }
+
+    if (length)
+    {
+      uint8_t* input = NULL;
+      uint16_t block_size;
+      size_t   in_length = sizeof (block_size);
+      int      decompressed;
+
+      if (!rtems_rtl_obj_cache_read (comp->cache, comp->fd, comp->offset,
+                                     (void**) &input, &in_length))
+        return false;
+
+      block_size = (input[0] << 8) | input[1];
+
+      comp->offset += sizeof (block_size);
+
+      in_length = block_size;
+
+      if (!rtems_rtl_obj_cache_read (comp->cache, comp->fd, comp->offset,
+                                     (void**) &input, &in_length))
+        return false;
+
+      if (in_length != block_size)
+      {
+        rtems_rtl_set_error (EIO, "compressed read failed: bs=%u in=%u",
+                             block_size, in_length);
+        return false;
+      }
+
+      switch (comp->compression)
+      {
+        case RTEMS_RTL_COMP_NONE:
+          memcpy (comp->buffer, input, in_length);
+          decompressed = in_length;
+          break;
+
+        case RTEMS_RTL_COMP_LZ77:
+          decompressed = fastlz_decompress (input, in_length,
+                                            comp->buffer, comp->size);
+          if (decompressed == 0)
+          {
+            rtems_rtl_set_error (EBADF, "decompression failed");
+            return false;
+          }
+          break;
+
+        default:
+          rtems_rtl_set_error (EINVAL, "bad compression type");
+          return false;
+      }
+
+      comp->offset += block_size;
+
+      comp->level = decompressed;
+    }
+  }
+
+  return true;
+}
diff --git a/cpukit/libdl/rtl-obj-comp.h b/cpukit/libdl/rtl-obj-comp.h
new file mode 100644
index 0000000..df7a429
--- /dev/null
+++ b/cpukit/libdl/rtl-obj-comp.h
@@ -0,0 +1,122 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object File Compression manages a
+ *        compressed stream of data.
+ *
+ * This is a simple interface to the object file cache to stream data from
+ * from a compressed object file. There is no ability to seek with the
+ * data from a compressed file. The module exists to allocate the output
+ * buffer when the loader starts and use the cache buffers will have been
+ * allocated.
+ */
+
+#if !defined (_RTEMS_RTL_OBJ_COMP_H_)
+#define _RTEMS_RTL_OBJ_COMP_H_
+
+#include <rtems/rtl/rtl-obj-cache.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * The amount of input data read at a time from the file.
+ */
+#define RTEMS_RTL_DECOMP_INPUT_SIZE (256)
+
+/**
+ * The types of supported compression.
+ */
+#define RTEMS_RTL_COMP_NONE (0)
+#define RTEMS_RTL_COMP_LZ77 (1)
+
+/**
+ * The compressed file.
+ */
+typedef struct rtems_rtl_obj_cpmp_s
+{
+  rtems_rtl_obj_cache_t* cache;       /**< The cache provides the input
+                                       *   buffer. */
+  int                    fd;          /**< The file descriptor. */
+  int                    compression; /**< The type of compression. */
+  off_t                  offset;      /**< The base offset of the buffer. */
+  size_t                 size;        /**< The size of the output buffer. */
+  size_t                 level;       /**< The amount of data in the buffer. */
+  uint8_t*               buffer;      /**< The buffer */
+  uint32_t               read;        /**< The amount of data read. */
+} rtems_rtl_obj_comp_t;
+
+/**
+ * Return the input level.
+ */
+static inline uint32_t rtems_rtl_obj_comp_input (rtems_rtl_obj_comp_t* comp)
+{
+  return comp->read;
+}
+
+/**
+ * Open a compressor allocating the output buffer.
+ *
+ * @param comp The compressor  to initialise.
+ * @param size The size of the compressor's output buffer.
+ * @retval true The compressor is open.
+ * @retval false The compressor is not open. The RTL error is set.
+ */
+bool rtems_rtl_obj_comp_open (rtems_rtl_obj_comp_t*  comp,
+                              size_t                 size);
+
+/**
+ * Close a compressor.
+ *
+ * @param comp The compressor to close.
+ */
+void rtems_rtl_obj_comp_close (rtems_rtl_obj_comp_t* comp);
+
+/**
+ * Set the cache and offset in the file the compressed stream starts.
+ *
+ * @param comp The compressor to set the offset in.
+ * @param cache The cache to read the file in by.
+ * @param fd The file descriptor. Must be an open file.
+ * @param compression The type of compression being streamed.
+ * @param offset The offset in the file the compressed stream starts.
+ */
+void rtems_rtl_obj_comp_set (rtems_rtl_obj_comp_t*  comp,
+                             rtems_rtl_obj_cache_t* cache,
+                             int                    fd,
+                             int                    compression,
+                             off_t                  offset);
+
+/**
+ * Read decompressed data. The length contains the amount of data that should
+ * be available in the cache and referenced by the buffer handle. It must be
+ * less than or equal to the size of the cache. This call will return the
+ * amount of data that is available. It can be less than you ask if the offset
+ * and size is past the end of the file.
+ *
+ * @param comp The compressor to read data from.
+ * @param buffer The buffer the output is written too.
+ * @param length The length of data to read. Can be modified to a
+ *               lesser value and true is still returned so check it.
+ * @retval true The data referenced is in the cache.
+ * @retval false The read failed and the RTL error has been set.
+ */
+bool rtems_rtl_obj_comp_read (rtems_rtl_obj_comp_t* comp,
+                              void*                 buffer,
+                              size_t                length);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/libdl/rtl-obj-fwd.h b/cpukit/libdl/rtl-obj-fwd.h
new file mode 100644
index 0000000..c4186d9
--- /dev/null
+++ b/cpukit/libdl/rtl-obj-fwd.h
@@ -0,0 +1,39 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker ELF Headers
+ */
+
+#if !defined (_RTEMS_RTL_OBJ_FWD_H_)
+#define _RTEMS_RTL_OBJ_FWD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * The forward declaration of the obj section structure.
+ */
+struct rtems_rtl_obj_sect_s;
+typedef struct rtems_rtl_obj_sect_s rtems_rtl_obj_sect_t;
+
+/**
+ * The forward declaration of the obj structure.
+ */
+struct rtems_rtl_obj_s;
+typedef struct rtems_rtl_obj_s rtems_rtl_obj_t;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/libdl/rtl-obj.c b/cpukit/libdl/rtl-obj.c
new file mode 100644
index 0000000..d4ee63c
--- /dev/null
+++ b/cpukit/libdl/rtl-obj.c
@@ -0,0 +1,1031 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtl
+ *
+ * @brief RTEMS Run-Time Linker Error
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <rtems/libio_.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-chain-iterator.h"
+#include "rtl-obj.h"
+#include "rtl-error.h"
+#include "rtl-find-file.h"
+#include "rtl-string.h"
+#include "rtl-trace.h"
+
+#if RTEMS_RTL_RAP_LOADER
+#include "rtl-rap.h"
+#define RTEMS_RTL_RAP_LOADER_COUNT 1
+#else
+#define RTEMS_RTL_RAP_LOADER_COUNT 0
+#endif
+
+#if RTEMS_RTL_ELF_LOADER
+#include "rtl-elf.h"
+#define RTEMS_RTL_ELF_LOADER_COUNT 1
+#else
+#define RTEMS_RTL_ELF_LOADER_COUNT 0
+#endif
+
+/**
+ * The table of supported loader formats.
+ */
+static rtems_rtl_loader_table_t loaders[RTEMS_RTL_ELF_LOADER_COUNT +
+                                        RTEMS_RTL_RAP_LOADER_COUNT] =
+{
+#if RTEMS_RTL_RAP_LOADER
+  { rtems_rtl_rap_file_check, rtems_rtl_rap_file_load, rtems_rtl_rap_file_sig },
+#endif
+#if RTEMS_RTL_ELF_LOADER
+  { rtems_rtl_elf_file_check, rtems_rtl_elf_file_load, rtems_rtl_elf_file_sig },
+#endif
+};
+
+rtems_rtl_obj_t*
+rtems_rtl_obj_alloc (void)
+{
+  rtems_rtl_obj_t* obj = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
+                                              sizeof (rtems_rtl_obj_t),
+                                              true);
+  if (obj)
+  {
+    /*
+     * Initialise the chains.
+     */
+    rtems_chain_initialize_empty (&obj->sections);
+  }
+  return obj;
+}
+
+static void
+rtems_rtl_obj_free_names (rtems_rtl_obj_t* obj)
+{
+  if (rtems_rtl_obj_oname_valid (obj))
+    rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) obj->oname);
+  if (rtems_rtl_obj_aname_valid (obj))
+    rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) obj->aname);
+  if (rtems_rtl_obj_fname_valid (obj))
+    rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) obj->fname);
+}
+
+bool
+rtems_rtl_obj_free (rtems_rtl_obj_t* obj)
+{
+  if (obj->users || ((obj->flags & RTEMS_RTL_OBJ_LOCKED) != 0))
+  {
+    rtems_rtl_set_error (EINVAL, "cannot free obj still in use");
+    return false;
+  }
+  if (!rtems_chain_is_node_off_chain (&obj->link))
+    rtems_chain_extract (&obj->link);
+  rtems_rtl_alloc_module_del (&obj->text_base, &obj->const_base,
+                              &obj->data_base, &obj->bss_base);
+  rtems_rtl_symbol_obj_erase (obj);
+  rtems_rtl_obj_free_names (obj);
+  if (obj->sec_num)
+    free (obj->sec_num);
+  if (obj->detail)
+    rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*)obj->detail);
+  rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, obj);
+  return true;
+}
+
+bool
+rtems_rtl_obj_unresolved (rtems_rtl_obj_t* obj)
+{
+  return (obj->flags & RTEMS_RTL_OBJ_UNRESOLVED) != 0 ? true : false;
+}
+
+bool
+rtems_rtl_parse_name (const char*  name,
+                      const char** aname,
+                      const char** oname,
+                      off_t*       ooffset)
+{
+  const char* laname = NULL;
+  const char* loname = NULL;
+  const char* colon;
+  const char* end;
+
+  /*
+   * Parse the name to determine if the object file is part of an archive or it
+   * is an object file. If an archive check the name for a '@' to see if the
+   * archive contains an offset.
+   */
+  end = name + strlen (name);
+  colon = strrchr (name, ':');
+  if (colon == NULL || colon < strrchr(name, '/'))
+    colon = end;
+
+  loname = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT, colon - name + 1, true);
+  if (!oname)
+  {
+    rtems_rtl_set_error (ENOMEM, "no memory for object file name");
+    return false;
+  }
+
+  memcpy ((void*) loname, name, colon - name);
+
+  /*
+   * If the pointers match there is no ':' delimiter.
+   */
+  if (colon != end)
+  {
+    const char* at;
+
+    /*
+     * The file name is an archive and the object file name is next after the
+     * delimiter. Move the pointer to the archive name.
+     */
+    laname = loname;
+    ++colon;
+
+    /*
+     * See if there is a '@' to delimit an archive offset for the object in the
+     * archive.
+     */
+    at = strchr (colon, '@');
+
+    if (at == NULL)
+      at = end;
+
+
+    loname = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT, at - colon + 1, true);
+    if (!loname)
+    {
+      rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) laname);
+      rtems_rtl_set_error (ENOMEM, "no memory for object file name");
+      return false;
+    }
+
+    memcpy ((void*) loname, colon, at - colon);
+
+    if (at != end)
+    {
+      /*
+       * The object name has an archive offset. If the number
+       * does not parse 0 will be returned and the archive will be
+       * searched.
+       */
+      *ooffset = strtoul (at + 1, 0, 0);
+    }
+  }
+
+  *oname = loname;
+  *aname = laname;
+  return true;
+}
+
+static bool
+rtems_rtl_obj_parse_name (rtems_rtl_obj_t* obj, const char* name)
+{
+  return rtems_rtl_parse_name (name, &(obj->aname), &(obj->oname), &(obj->ooffset));
+}
+
+static bool
+rtems_rtl_seek_read (int fd, off_t off, size_t len, uint8_t* buffer)
+{
+  if (lseek (fd, off, SEEK_SET) < 0)
+    return false;
+  if (read (fd, buffer, len) != len)
+    return false;
+  return true;
+}
+
+/**
+ * Scan the decimal number returning the value found.
+ */
+static uint64_t
+rtems_rtl_scan_decimal (const uint8_t* string, size_t len)
+{
+  uint64_t value = 0;
+
+  while (len && (*string != ' '))
+  {
+    value *= 10;
+    value += *string - '0';
+    ++string;
+    --len;
+  }
+
+  return value;
+}
+
+/**
+ * Align the size to the next alignment point. Assume the alignment is a
+ * positive integral power of 2 if not 0 or 1. If 0 or 1 then there is no
+ * alignment.
+ */
+static size_t
+rtems_rtl_sect_align (size_t offset, uint32_t alignment)
+{
+  if ((alignment > 1) && ((offset & ~alignment) != 0))
+    offset = (offset + alignment) & ~(alignment - 1);
+  return offset;
+}
+
+/**
+ * Section size summer iterator data.
+ */
+typedef struct
+{
+  uint32_t mask; /**< The selection mask to sum. */
+  size_t   size; /**< The size of all section fragments. */
+} rtems_rtl_obj_sect_summer_t;
+
+static bool
+rtems_rtl_obj_sect_summer (rtems_chain_node* node, void* data)
+{
+  rtems_rtl_obj_sect_t*        sect = (rtems_rtl_obj_sect_t*) node;
+  rtems_rtl_obj_sect_summer_t* summer = data;
+  if ((sect->flags & summer->mask) == summer->mask)
+    summer->size =
+      rtems_rtl_sect_align (summer->size, sect->alignment) + sect->size;
+  return true;
+}
+
+static size_t
+rtems_rtl_obj_section_size (rtems_rtl_obj_t* obj, uint32_t mask)
+{
+  rtems_rtl_obj_sect_summer_t summer;
+  summer.mask = mask;
+  summer.size = 0;
+  rtems_rtl_chain_iterate (&obj->sections,
+                           rtems_rtl_obj_sect_summer,
+                           &summer);
+  return summer.size;
+}
+
+/**
+ * Section alignment iterator data. The first section's alignment sets the
+ * alignment for that type of section.
+ */
+typedef struct
+{
+  uint32_t mask;      /**< The selection mask to look for alignment. */
+  uint32_t alignment; /**< The alignment of the section type. */
+} rtems_rtl_obj_sect_aligner_t;
+
+/**
+ * The section aligner iterator.
+ */
+static bool
+rtems_rtl_obj_sect_aligner (rtems_chain_node* node, void* data)
+{
+  rtems_rtl_obj_sect_t*         sect = (rtems_rtl_obj_sect_t*) node;
+  rtems_rtl_obj_sect_aligner_t* aligner = data;
+  if ((sect->flags & aligner->mask) == aligner->mask)
+  {
+    aligner->alignment = sect->alignment;
+    return false;
+  }
+  return true;
+}
+
+static size_t
+rtems_rtl_obj_section_alignment (rtems_rtl_obj_t* obj, uint32_t mask)
+{
+  rtems_rtl_obj_sect_aligner_t aligner;
+  aligner.mask = mask;
+  aligner.alignment = 0;
+  rtems_rtl_chain_iterate (&obj->sections,
+                           rtems_rtl_obj_sect_aligner,
+                           &aligner);
+  return aligner.alignment;
+}
+
+static bool
+rtems_rtl_obj_section_handler (uint32_t                     mask,
+                               rtems_rtl_obj_t*             obj,
+                               int                          fd,
+                               rtems_rtl_obj_sect_handler_t handler,
+                               void*                        data)
+{
+  rtems_chain_node* node = rtems_chain_first (&obj->sections);
+  while (!rtems_chain_is_tail (&obj->sections, node))
+  {
+    rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
+    if ((sect->flags & mask) != 0)
+    {
+      if (!handler (obj, fd, sect, data))
+        return false;
+    }
+    node = rtems_chain_next (node);
+  }
+  return true;
+}
+
+bool
+rtems_rtl_match_name (rtems_rtl_obj_t* obj, const char* name)
+{
+  const char* n1 = obj->oname;
+  while ((*n1 != '\0') && (*n1 != '\n') && (*n1 != '/') &&
+         (*name != '\0') && (*name != '/') && (*n1 == *name))
+  {
+    ++n1;
+    ++name;
+  }
+  if (((*n1 == '\0') || (*n1 == '\n') || (*n1 == '/')) &&
+      ((*name == '\0') || (*name == '/')))
+    return true;
+  return false;
+}
+
+bool
+rtems_rtl_obj_find_file (rtems_rtl_obj_t* obj, const char* name)
+{
+  const char*       pname;
+  rtems_rtl_data_t* rtl;
+
+  /*
+   * Parse the name. The object descriptor will have the archive name and/or
+   * object name fields filled in. A find of the file will result in the file
+   * name (fname) field pointing to the actual file if present on the file
+   * system.
+   */
+  if (!rtems_rtl_obj_parse_name (obj, name))
+    return false;
+
+  /*
+   * If the archive field (aname) is set we use that name else we use the
+   * object field (oname). If selected name is absolute we just point the aname
+   * field to the fname field to that name. If the field is relative we search
+   * the paths set in the RTL for the file.
+   */
+  if (rtems_rtl_obj_aname_valid (obj))
+    pname = rtems_rtl_obj_aname (obj);
+  else
+    pname = rtems_rtl_obj_oname (obj);
+
+  rtl = rtems_rtl_lock ();
+
+  if (!rtems_rtl_find_file (pname, rtl->paths, &obj->fname, &obj->fsize))
+  {
+    rtems_rtl_set_error (ENOENT, "file not found");
+    rtems_rtl_unlock ();
+    return false;
+  }
+
+  rtems_rtl_unlock ();
+
+  return true;
+}
+
+bool
+rtems_rtl_obj_add_section (rtems_rtl_obj_t* obj,
+                           int              section,
+                           const char*      name,
+                           size_t           size,
+                           off_t            offset,
+                           uint32_t         alignment,
+                           int              link,
+                           int              info,
+                           uint32_t         flags)
+{
+  rtems_rtl_obj_sect_t* sect = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
+                                                    sizeof (rtems_rtl_obj_sect_t), true);
+  if (!sect)
+  {
+    rtems_rtl_set_error (ENOMEM, "adding allocated section");
+    return false;
+  }
+  sect->section = section;
+  sect->name = rtems_rtl_strdup (name);
+  sect->size = size;
+  sect->offset = offset;
+  sect->alignment = alignment;
+  sect->link = link;
+  sect->info = info;
+  sect->flags = flags;
+  sect->base = NULL;
+  rtems_chain_append (&obj->sections, &sect->node);
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_SECTION))
+    printf ("rtl: sect: %-2d: %s\n", section, name);
+
+  return true;
+}
+
+void
+rtems_rtl_obj_erase_sections (rtems_rtl_obj_t* obj)
+{
+  rtems_chain_node* node = rtems_chain_first (&obj->sections);
+  while (!rtems_chain_is_tail (&obj->sections, node))
+  {
+    rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
+    rtems_chain_node*     next_node = rtems_chain_next (node);
+    rtems_chain_extract (node);
+    rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) sect->name);
+    rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, sect);
+    node = next_node;
+  }
+}
+
+/**
+ * Section finder iterator data.
+ */
+typedef struct
+{
+  rtems_rtl_obj_sect_t*  sect;  /**< The matching section. */
+  const char*            name;  /**< The name to match. */
+  int                    index; /**< The index to match. */
+} rtems_rtl_obj_sect_finder_t;
+
+static bool
+rtems_rtl_obj_sect_match_name (rtems_chain_node* node, void* data)
+{
+  rtems_rtl_obj_sect_t*        sect = (rtems_rtl_obj_sect_t*) node;
+  rtems_rtl_obj_sect_finder_t* match = data;
+  if (strcmp (sect->name, match->name) == 0)
+  {
+    match->sect = sect;
+    return false;
+  }
+  return true;
+}
+
+rtems_rtl_obj_sect_t*
+rtems_rtl_obj_find_section (rtems_rtl_obj_t* obj, const char* name)
+{
+  rtems_rtl_obj_sect_finder_t match;
+  match.sect = NULL;
+  match.name = name;
+  rtems_rtl_chain_iterate (&obj->sections,
+                           rtems_rtl_obj_sect_match_name,
+                           &match);
+  return match.sect;
+}
+
+static bool
+rtems_rtl_obj_sect_match_index (rtems_chain_node* node, void* data)
+{
+  rtems_rtl_obj_sect_t*        sect = (rtems_rtl_obj_sect_t*) node;
+  rtems_rtl_obj_sect_finder_t* match = data;
+  if (sect->section == match->index)
+  {
+    match->sect = sect;
+    return false;
+  }
+  return true;
+}
+
+rtems_rtl_obj_sect_t*
+rtems_rtl_obj_find_section_by_index (rtems_rtl_obj_t* obj, int index)
+{
+  rtems_rtl_obj_sect_finder_t match;
+  match.sect = NULL;
+  match.index = index;
+  rtems_rtl_chain_iterate (&obj->sections,
+                           rtems_rtl_obj_sect_match_index,
+                           &match);
+  return match.sect;
+}
+
+size_t
+rtems_rtl_obj_text_size (rtems_rtl_obj_t* obj)
+{
+  return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_TEXT);
+}
+
+uint32_t
+rtems_rtl_obj_text_alignment (rtems_rtl_obj_t* obj)
+{
+  return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_TEXT);
+}
+
+size_t
+rtems_rtl_obj_const_size (rtems_rtl_obj_t* obj)
+{
+  return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_CONST);
+}
+
+uint32_t
+rtems_rtl_obj_const_alignment (rtems_rtl_obj_t* obj)
+{
+  return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_CONST);
+}
+
+size_t
+rtems_rtl_obj_data_size (rtems_rtl_obj_t* obj)
+{
+  return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_DATA);
+}
+
+uint32_t
+rtems_rtl_obj_data_alignment (rtems_rtl_obj_t* obj)
+{
+  return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_DATA);
+}
+
+size_t
+rtems_rtl_obj_bss_size (rtems_rtl_obj_t* obj)
+{
+  return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_BSS);
+}
+
+uint32_t
+rtems_rtl_obj_bss_alignment (rtems_rtl_obj_t* obj)
+{
+  return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_BSS);
+}
+
+bool
+rtems_rtl_obj_relocate (rtems_rtl_obj_t*             obj,
+                        int                          fd,
+                        rtems_rtl_obj_sect_handler_t handler,
+                        void*                        data)
+{
+  uint32_t mask = RTEMS_RTL_OBJ_SECT_REL | RTEMS_RTL_OBJ_SECT_RELA;
+  return rtems_rtl_obj_section_handler (mask, obj, fd, handler, data);
+}
+
+bool
+rtems_rtl_obj_load_symbols (rtems_rtl_obj_t*             obj,
+                            int                          fd,
+                            rtems_rtl_obj_sect_handler_t handler,
+                            void*                        data)
+{
+  uint32_t mask = RTEMS_RTL_OBJ_SECT_SYM;
+  return rtems_rtl_obj_section_handler (mask, obj, fd, handler, data);
+}
+
+static size_t
+rtems_rtl_obj_sections_loader (uint32_t                     mask,
+                               rtems_rtl_obj_t*             obj,
+                               int                          fd,
+                               uint8_t*                     base,
+                               rtems_rtl_obj_sect_handler_t handler,
+                               void*                        data)
+{
+  rtems_chain_control* sections = &obj->sections;
+  rtems_chain_node*    node = rtems_chain_first (sections);
+  size_t               base_offset = 0;
+  bool                 first = true;
+  while (!rtems_chain_is_tail (sections, node))
+  {
+    rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
+
+    if ((sect->size != 0) && ((sect->flags & mask) != 0))
+    {
+      if (!first)
+        base_offset = rtems_rtl_sect_align (base_offset, sect->alignment);
+
+      sect->base = base + base_offset;
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
+        printf ("rtl: loading: %s -> %8p (%zi)\n",
+                sect->name, sect->base, sect->size);
+
+      if ((sect->flags & RTEMS_RTL_OBJ_SECT_LOAD) == RTEMS_RTL_OBJ_SECT_LOAD)
+      {
+        if (!handler (obj, fd, sect, data))
+        {
+          sect->base = 0;
+          return false;
+        }
+      }
+      else if ((sect->flags & RTEMS_RTL_OBJ_SECT_ZERO) == RTEMS_RTL_OBJ_SECT_ZERO)
+      {
+        memset (base + base_offset, 0, sect->size);
+      }
+      else
+      {
+        sect->base = 0;
+        rtems_rtl_set_error (errno, "section has no load op");
+        return false;
+      }
+
+      base_offset += sect->size;
+      first = false;
+    }
+
+    node = rtems_chain_next (node);
+  }
+
+  return true;
+}
+
+bool
+rtems_rtl_obj_load_sections (rtems_rtl_obj_t*             obj,
+                             int                          fd,
+                             rtems_rtl_obj_sect_handler_t handler,
+                             void*                        data)
+{
+  size_t text_size;
+  size_t const_size;
+  size_t data_size;
+  size_t bss_size;
+
+  text_size  = rtems_rtl_obj_text_size (obj) + rtems_rtl_obj_const_alignment (obj);
+  const_size = rtems_rtl_obj_const_size (obj) + rtems_rtl_obj_data_alignment (obj);
+  data_size  = rtems_rtl_obj_data_size (obj) + rtems_rtl_obj_bss_alignment (obj);
+  bss_size   = rtems_rtl_obj_bss_size (obj);
+
+  /*
+   * Let the allocator manage the actual allocation. The user can use the
+   * standard heap or provide a specific allocator with memory protection.
+   */
+  if (!rtems_rtl_alloc_module_new (&obj->text_base, text_size,
+                                   &obj->const_base, const_size,
+                                   &obj->data_base, data_size,
+                                   &obj->bss_base, bss_size))
+  {
+    obj->exec_size = 0;
+    rtems_rtl_set_error (ENOMEM, "no memory to load obj");
+    return false;
+  }
+
+  obj->exec_size = text_size + const_size + data_size + bss_size;
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
+  {
+    printf ("rtl: load sect: text  - b:%p s:%zi a:%" PRIu32 "\n",
+            obj->text_base, text_size, rtems_rtl_obj_text_alignment (obj));
+    printf ("rtl: load sect: const - b:%p s:%zi a:%" PRIu32 "\n",
+            obj->const_base, const_size, rtems_rtl_obj_const_alignment (obj));
+    printf ("rtl: load sect: data  - b:%p s:%zi a:%" PRIu32 "\n",
+            obj->data_base, data_size, rtems_rtl_obj_data_alignment (obj));
+    printf ("rtl: load sect: bss   - b:%p s:%zi a:%" PRIu32 "\n",
+            obj->bss_base, bss_size, rtems_rtl_obj_bss_alignment (obj));
+  }
+
+  /*
+   * Load all text then data then bss sections in seperate operations so each
+   * type of section is grouped together.
+   */
+  if (!rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_TEXT,
+                                      obj, fd, obj->text_base, handler, data) ||
+      !rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_CONST,
+                                      obj, fd, obj->const_base, handler, data) ||
+      !rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_DATA,
+                                      obj, fd, obj->data_base, handler, data) ||
+      !rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_BSS,
+                                      obj, fd, obj->bss_base, handler, data))
+  {
+    rtems_rtl_alloc_module_del (&obj->text_base, &obj->const_base,
+                                &obj->data_base, &obj->bss_base);
+    obj->exec_size = 0;
+    return false;
+  }
+
+  return true;
+}
+
+static void
+rtems_rtl_obj_run_cdtors (rtems_rtl_obj_t* obj, uint32_t mask)
+{
+  rtems_chain_node* node = rtems_chain_first (&obj->sections);
+  while (!rtems_chain_is_tail (&obj->sections, node))
+  {
+    rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
+    if ((sect->flags & mask) == mask)
+    {
+      rtems_rtl_cdtor_t* handler;
+      size_t             handlers = sect->size / sizeof (rtems_rtl_cdtor_t);
+      int                c;
+      for (c = 0, handler = sect->base; c < handlers; ++c)
+        if (*handler)
+          (*handler) ();
+    }
+    node = rtems_chain_next (node);
+  }
+}
+
+void
+rtems_rtl_obj_run_ctors (rtems_rtl_obj_t* obj)
+{
+  return rtems_rtl_obj_run_cdtors (obj, RTEMS_RTL_OBJ_SECT_CTOR);
+}
+
+void
+rtems_rtl_obj_run_dtors (rtems_rtl_obj_t* obj)
+{
+  return rtems_rtl_obj_run_cdtors (obj, RTEMS_RTL_OBJ_SECT_DTOR);
+}
+
+/**
+ * Find a module in an archive returning the offset in the archive in the
+ * object descriptor.
+ */
+static bool
+rtems_rtl_obj_archive_find (rtems_rtl_obj_t* obj, int fd)
+{
+#define RTEMS_RTL_AR_IDENT      "!<arch>\n"
+#define RTEMS_RTL_AR_IDENT_SIZE (sizeof (RTEMS_RTL_AR_IDENT) - 1)
+#define RTEMS_RTL_AR_FHDR_BASE  RTEMS_RTL_AR_IDENT_SIZE
+#define RTEMS_RTL_AR_FNAME      (0)
+#define RTEMS_RTL_AR_FNAME_SIZE (16)
+#define RTEMS_RTL_AR_SIZE       (48)
+#define RTEMS_RTL_AR_SIZE_SIZE  (10)
+#define RTEMS_RTL_AR_MAGIC      (58)
+#define RTEMS_RTL_AR_MAGIC_SIZE (2)
+#define RTEMS_RTL_AR_FHDR_SIZE  (60)
+
+  size_t  fsize = obj->fsize;
+  off_t   extended_file_names;
+  uint8_t header[RTEMS_RTL_AR_FHDR_SIZE];
+  bool    scanning;
+
+  if (read (fd, &header[0], RTEMS_RTL_AR_IDENT_SIZE) !=  RTEMS_RTL_AR_IDENT_SIZE)
+  {
+    rtems_rtl_set_error (errno, "reading archive identifer");
+    return false;
+  }
+
+  if (memcmp (header, RTEMS_RTL_AR_IDENT, RTEMS_RTL_AR_IDENT_SIZE) != 0)
+  {
+    rtems_rtl_set_error (EINVAL, "invalid archive identifer");
+    return false;
+  }
+
+  /*
+   * Seek to the current offset in the archive and if we have a valid archive
+   * file header present check the file name for a match with the oname field
+   * of the object descriptor. If the archive header is not valid and it is the
+   * first pass reset the offset and start the search again in case the offset
+   * provided is not valid any more.
+   *
+   * The archive can have a symbol table at the start. Ignore it. A symbol
+   * table has the file name '/'.
+   *
+   * The archive can also have the GNU extended file name table. This
+   * complicates the processing. If the object's file name starts with '/' the
+   * remainder of the file name is an offset into the extended file name
+   * table. To find the extended file name table we need to scan from start of
+   * the archive for a file name of '//'. Once found we remeber the table's
+   * start and can direct seek to file name location. In other words the scan
+   * only happens once.
+   *
+   * If the name had the offset encoded we go straight to that location.
+   */
+
+  if (obj->ooffset != 0)
+    scanning = false;
+  else
+  {
+    scanning = true;
+    obj->ooffset = RTEMS_RTL_AR_FHDR_BASE;
+  }
+
+  extended_file_names = 0;
+
+  while (obj->ooffset < fsize)
+  {
+    /*
+     * Clean up any existing data.
+     */
+    memset (header, 0, sizeof (header));
+
+    if (!rtems_rtl_seek_read (fd, obj->ooffset, RTEMS_RTL_AR_FHDR_SIZE, &header[0]))
+    {
+      rtems_rtl_set_error (errno, "seek/read archive file header");
+      obj->ooffset = 0;
+      obj->fsize = 0;
+      return false;
+    }
+
+    if ((header[RTEMS_RTL_AR_MAGIC] != 0x60) ||
+        (header[RTEMS_RTL_AR_MAGIC + 1] != 0x0a))
+    {
+      if (scanning)
+      {
+        rtems_rtl_set_error (EINVAL, "invalid archive file header");
+        obj->ooffset = 0;
+        obj->fsize = 0;
+        return false;
+      }
+
+      scanning = true;
+      obj->ooffset = RTEMS_RTL_AR_FHDR_BASE;
+      continue;
+    }
+
+    /*
+     * The archive header is always aligned to an even address.
+     */
+    obj->fsize = (rtems_rtl_scan_decimal (&header[RTEMS_RTL_AR_SIZE],
+                                          RTEMS_RTL_AR_SIZE_SIZE) + 1) & ~1;
+
+    /*
+     * Check for the GNU extensions.
+     */
+    if (header[0] == '/')
+    {
+      off_t extended_off;
+
+      switch (header[1])
+      {
+        case ' ':
+          /*
+           * Symbols table. Ignore the table.
+           */
+          break;
+        case '/':
+          /*
+           * Extended file names table. Remember.
+           */
+          extended_file_names = obj->ooffset + RTEMS_RTL_AR_FHDR_SIZE;
+          break;
+        case '0':
+        case '1':
+        case '2':
+        case '3':
+        case '4':
+        case '5':
+        case '6':
+        case '7':
+        case '8':
+        case '9':
+          /*
+           * Offset into the extended file name table. If we do not have the
+           * offset to the extended file name table find it.
+           */
+          extended_off =
+            rtems_rtl_scan_decimal (&header[1], RTEMS_RTL_AR_FNAME_SIZE);
+
+          if (extended_file_names == 0)
+          {
+            off_t off = obj->ooffset;
+            while (extended_file_names == 0)
+            {
+              off_t esize =
+                (rtems_rtl_scan_decimal (&header[RTEMS_RTL_AR_SIZE],
+                                         RTEMS_RTL_AR_SIZE_SIZE) + 1) & ~1;
+              off += esize + RTEMS_RTL_AR_FHDR_SIZE;
+
+              if (!rtems_rtl_seek_read (fd, off,
+                                        RTEMS_RTL_AR_FHDR_SIZE, &header[0]))
+              {
+                rtems_rtl_set_error (errno,
+                                     "seeking/reading archive ext file name header");
+                obj->ooffset = 0;
+                obj->fsize = 0;
+                return false;
+              }
+
+              if ((header[RTEMS_RTL_AR_MAGIC] != 0x60) ||
+                  (header[RTEMS_RTL_AR_MAGIC + 1] != 0x0a))
+              {
+                rtems_rtl_set_error (errno, "invalid archive file header");
+                obj->ooffset = 0;
+                obj->fsize = 0;
+                return false;
+              }
+
+              if ((header[0] == '/') && (header[1] == '/'))
+              {
+                extended_file_names = off + RTEMS_RTL_AR_FHDR_SIZE;
+                break;
+              }
+            }
+          }
+
+          if (extended_file_names)
+          {
+            /*
+             * We know the offset in the archive to the extended file. Read the
+             * name from the table and compare with the name we are after.
+             */
+#define RTEMS_RTL_MAX_FILE_SIZE (256)
+            char  name[RTEMS_RTL_MAX_FILE_SIZE];
+
+            if (!rtems_rtl_seek_read (fd, extended_file_names + extended_off,
+                                      RTEMS_RTL_MAX_FILE_SIZE, (uint8_t*) &name[0]))
+            {
+              rtems_rtl_set_error (errno,
+                                   "invalid archive ext file seek/read");
+              obj->ooffset = 0;
+              obj->fsize = 0;
+              return false;
+            }
+
+            if (rtems_rtl_match_name (obj, name))
+            {
+              obj->ooffset += RTEMS_RTL_AR_FHDR_SIZE;
+              return true;
+            }
+          }
+          break;
+        default:
+          /*
+           * Ignore the file because we do not know what it it.
+           */
+          break;
+      }
+    }
+    else
+    {
+      if (rtems_rtl_match_name (obj, (const char*) &header[RTEMS_RTL_AR_FNAME]))
+      {
+        obj->ooffset += RTEMS_RTL_AR_FHDR_SIZE;
+        return true;
+      }
+    }
+
+    obj->ooffset += obj->fsize + RTEMS_RTL_AR_FHDR_SIZE;
+  }
+
+  rtems_rtl_set_error (ENOENT, "object file not found");
+  obj->ooffset = 0;
+  obj->fsize = 0;
+  return false;
+}
+
+bool
+rtems_rtl_obj_file_load (rtems_rtl_obj_t* obj, int fd)
+{
+  int l;
+
+  for (l = 0; l < (sizeof (loaders) / sizeof (rtems_rtl_loader_table_t)); ++l)
+  {
+    if (loaders[l].check (obj, fd))
+      return loaders[l].load (obj, fd);
+  }
+
+  rtems_rtl_set_error (ENOENT, "no format loader found");
+  return false;
+}
+
+bool
+rtems_rtl_obj_load (rtems_rtl_obj_t* obj)
+{
+  int fd;
+
+  if (!rtems_rtl_obj_fname_valid (obj))
+  {
+    rtems_rtl_set_error (ENOMEM, "invalid object file name path");
+    return false;
+  }
+
+  fd = open (rtems_rtl_obj_fname (obj), O_RDONLY);
+  if (fd < 0)
+  {
+    rtems_rtl_set_error (ENOMEM, "opening for object file");
+    return false;
+  }
+
+  /*
+   * Find the object file in the archive if it is an archive that
+   * has been opened.
+   */
+  if (rtems_rtl_obj_aname_valid (obj))
+  {
+    if (!rtems_rtl_obj_archive_find (obj, fd))
+    {
+      rtems_rtl_obj_caches_flush ();
+      close (fd);
+      return false;
+    }
+  }
+
+  /*
+   * Call the format specific loader. Currently this is a call to the ELF
+   * loader. This call could be changed to allow probes then calls if more than
+   * one format is supported.
+   */
+  if (!rtems_rtl_obj_file_load (obj, fd))
+  {
+    rtems_rtl_obj_caches_flush ();
+    close (fd);
+    return false;
+  }
+
+  if (!_rtld_linkmap_add (obj)) /* For GDB */
+  {
+    close (fd);
+    return false;
+  }
+
+  rtems_rtl_obj_caches_flush ();
+
+  close (fd);
+
+  return true;
+}
+
+bool
+rtems_rtl_obj_unload (rtems_rtl_obj_t* obj)
+{
+  _rtld_linkmap_delete(obj);
+  rtems_rtl_symbol_obj_erase (obj);
+  return rtems_rtl_obj_free (obj);
+}
diff --git a/cpukit/libdl/rtl-obj.h b/cpukit/libdl/rtl-obj.h
new file mode 100644
index 0000000..0550723
--- /dev/null
+++ b/cpukit/libdl/rtl-obj.h
@@ -0,0 +1,580 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object Support.
+ */
+
+#if !defined (_RTEMS_RTL_OBJ_H_)
+#define _RTEMS_RTL_OBJ_H_
+
+#include <rtems.h>
+#include <rtems/chain.h>
+#include <rtems/rtl/rtl-sym.h>
+#include <rtems/rtl/rtl-unresolved.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Loader format flags.
+ */
+#define RTEMS_RTL_FMT_ELF     (1 << 0)
+#define RTEMS_RTL_FMT_COMP    (1 << 1)
+#define RTEMS_RTL_FMT_PRIVATE (1 << 16)
+
+/**
+ * Loader format definition.
+ */
+typedef struct rtems_rtl_loader_format_s
+{
+  /**
+   * The format label. This can be used to determine and manage
+   * specific formats.
+   */
+  const char* label;
+
+  /**
+   * The format flags.
+   */
+  uint32_t flags;
+} rtems_rtl_loader_format_t;
+
+/**
+ * The type of the format loader check handler. This handler checks the format
+ * and if it is detected as suitable it returns true.
+ */
+typedef bool (*rtems_rtl_loader_check) (rtems_rtl_obj_t* obj, int fd);
+
+/**
+ * The type of the format loader handler. This handler loads the specific
+ * format.
+ */
+typedef bool (*rtems_rtl_loader_load) (rtems_rtl_obj_t* obj, int fd);
+
+/**
+ * The type of the format loader handler. This handler loads the specific
+ * format.
+ */
+typedef rtems_rtl_loader_format_t* (*rtems_rtl_loader_sig) (void);
+
+/**
+ * Table for supported loadable formats.
+ */
+typedef struct rtems_rtl_loader_table_s
+{
+  rtems_rtl_loader_check check;     /**< The check handler. */
+  rtems_rtl_loader_load  load;      /**< The loader. */
+  rtems_rtl_loader_sig   signature; /**< The loader's signature. */
+} rtems_rtl_loader_table_t;
+
+/**
+ * Flags for the various section types.
+ */
+#define RTEMS_RTL_OBJ_SECT_TEXT  (1 << 0)  /**< Section holds program text. */
+#define RTEMS_RTL_OBJ_SECT_CONST (1 << 1)  /**< Section holds program text. */
+#define RTEMS_RTL_OBJ_SECT_DATA  (1 << 2)  /**< Section holds program data. */
+#define RTEMS_RTL_OBJ_SECT_BSS   (1 << 3)  /**< Section holds program bss. */
+#define RTEMS_RTL_OBJ_SECT_REL   (1 << 4)  /**< Section holds relocation records. */
+#define RTEMS_RTL_OBJ_SECT_RELA  (1 << 5)  /**< Section holds relocation addend
+                                            *   records. */
+#define RTEMS_RTL_OBJ_SECT_SYM   (1 << 6)  /**< Section holds symbols. */
+#define RTEMS_RTL_OBJ_SECT_STR   (1 << 7)  /**< Section holds strings. */
+#define RTEMS_RTL_OBJ_SECT_ALLOC (1 << 8)  /**< Section allocates runtime memory. */
+#define RTEMS_RTL_OBJ_SECT_LOAD  (1 << 9)  /**< Section is loaded from object file. */
+#define RTEMS_RTL_OBJ_SECT_WRITE (1 << 10) /**< Section is writable, ie data. */
+#define RTEMS_RTL_OBJ_SECT_EXEC  (1 << 11) /**< Section is executable. */
+#define RTEMS_RTL_OBJ_SECT_ZERO  (1 << 12) /**< Section is preset to zero. */
+#define RTEMS_RTL_OBJ_SECT_CTOR  (1 << 13) /**< Section contains constructors. */
+#define RTEMS_RTL_OBJ_SECT_DTOR  (1 << 14) /**< Section contains destructors. */
+
+/**
+ * An object file is made up of sections and the can be more than
+ * one of a specific type of sections. All sections and grouped
+ * together in memory.
+ */
+struct rtems_rtl_obj_sect_s
+{
+  rtems_chain_node node;        /**< The node's link in the chain. */
+  int              section;     /**< The section number. */
+  const char*      name;        /**< The section's name. */
+  size_t           size;        /**< The size of the section in memory. */
+  off_t            offset;      /**< Offset into the object file. Relative to
+                                 * the start of the object file. */
+  uint32_t         alignment;   /**< Alignment of this section. */
+  int              link;        /**< Section link field. */
+  int              info;        /**< Secfion info field. */
+  uint32_t         flags;       /**< The section's flags. */
+  void*            base;        /**< The base address of the section in
+                                 *   memory. */
+};
+
+/**
+ * Object file descriptor flags.
+ */
+#define RTEMS_RTL_OBJ_LOCKED     (1 << 0) /**< Lock the object file so it cannot
+                                           *   be unloaded. */
+#define RTEMS_RTL_OBJ_UNRESOLVED (1 << 1) /**< The object file has unresolved
+                                           *   external symbols. */
+
+/**
+ * RTL Object. There is one for each object module loaded plus one for the base
+ * kernel image.
+ */
+struct rtems_rtl_obj_s
+{
+  rtems_chain_node     link;         /**< The node's link in the chain. */
+  uint32_t             flags;        /**< The status of the object file. */
+  uint32_t             users;        /**< References to the object file. */
+  const char*          fname;        /**< The file name for the object. */
+  const char*          oname;        /**< The object file name. Can be
+                                      *   relative. */
+  const char*          aname;        /**< The archive name containing the
+                                      *   object. NULL means the object is not
+                                      *   in a lib */
+  off_t                ooffset;      /**< The object offset in the archive. */
+  size_t               fsize;        /**< Size of the object file. */
+  rtems_chain_control  sections;     /**< The sections of interest in the
+                                      *   object file. */
+  rtems_rtl_obj_sym_t* global_table; /**< Global symbol table. */
+  size_t               global_syms;  /**< Global symbol count. */
+  size_t               global_size;  /**< Global symbol memory usage. */
+  uint32_t             unresolved;   /**< The number of unresolved relocations. */
+  void*                text_base;    /**< The base address of the text section
+                                      * in memory. */
+  void*                const_base;   /**< The base address of the const section
+                                      * in memory. */
+  void*                data_base;    /**< The base address of the data section
+                                      * in memory. */
+  void*                bss_base;     /**< The base address of the bss section
+                                      * in memory. */
+  size_t               bss_size;     /**< The size of the bss section. */
+  size_t               exec_size;    /**< The amount of executable memory
+                                      * allocated */
+  void*                entry;        /**< The entry point of the module. */
+  uint32_t             checksum;     /**< The checksum of the text sections. A
+                                      * zero means do not checksum. */
+  void*                detail;       /**< The file details. It contains the elf file
+                                      * detail, mainly including elf file name,
+                                      * section offset, section size, which
+                                      * elf this section belongs to.*/
+  uint32_t*            sec_num;      /**< The sec nums of each obj. */
+  uint32_t             obj_num;      /**< The count of elf files in an rtl obj. */
+  struct link_map*     linkmap;      /**< For GDB. */
+};
+
+/**
+ * A section handler is called once for each section that needs to be
+ * processed by this handler.
+ *
+ * @param obj The object file's descriptor the section belongs too.
+ * @param fd The file descriptor of the object file beling loaded.
+ * @param sect The section the handler is being invoked to handle.
+ * @param data A user supplied data variable.
+ * @retval true The operation was successful.
+ * @retval false The operation failed and the RTL has been set.
+ */
+typedef bool (*rtems_rtl_obj_sect_handler_t)(rtems_rtl_obj_t*      obj,
+                                             int                   fd,
+                                             rtems_rtl_obj_sect_t* sect,
+                                             void*                 data);
+
+/**
+ * Get the file name.
+ *
+ * @param obj The object file.
+ * @return const char* The string.
+ */
+static inline const char* rtems_rtl_obj_fname (const rtems_rtl_obj_t* obj)
+{
+  return obj->fname;
+}
+
+/**
+ * Is the file name valid ?
+ *
+ * @param obj The object file.
+ * @return bool There is a file name
+ */
+static inline bool rtems_rtl_obj_fname_valid (const rtems_rtl_obj_t* obj)
+{
+  return obj->fname;
+}
+
+/**
+ * Get the object name.
+ *
+ * @param obj The object file.
+ * @return const char* The string.
+ */
+static inline const char* rtems_rtl_obj_oname (const rtems_rtl_obj_t* obj)
+{
+  return obj->oname;
+}
+
+/**
+ * Is the object name valid ?
+ *
+ * @param obj The object file.
+ * @return bool There is an object name
+ */
+static inline bool rtems_rtl_obj_oname_valid (const rtems_rtl_obj_t* obj)
+{
+  return obj->oname;
+}
+
+/**
+ * Get the archive name.
+ *
+ * @param obj The object file.
+ * @return const char* The string.
+ */
+static inline const char* rtems_rtl_obj_aname (const rtems_rtl_obj_t* obj)
+{
+  return obj->aname;
+}
+
+/**
+ * Is the archive name valid ?
+ *
+ * @param obj The object file.
+ * @return bool There is an archive name
+ */
+static inline bool rtems_rtl_obj_aname_valid (const rtems_rtl_obj_t* obj)
+{
+  return obj->aname;
+}
+
+/**
+ * Allocate an object structure on the heap.
+ *
+ * @retval NULL No memory for the object.
+ */
+rtems_rtl_obj_t* rtems_rtl_obj_alloc (void);
+
+/**
+ * Free the object structure and related resources.
+ *
+ * @param obj The object file's descriptor to free.
+ * @retval false The object has dependences.
+ * @retval true The object has been freed.
+ */
+bool rtems_rtl_obj_free (rtems_rtl_obj_t* obj);
+
+/**
+ * Does the object file have unresolved external references ? If it does the
+ * results of executing code is unpredictable.
+ *
+ * @param obj The object file's descriptor.
+ * @retval true The object file has unresolved externals.
+ * @retval false The object file has all external references resolved.
+ */
+bool rtems_rtl_obj_unresolved (rtems_rtl_obj_t* obj);
+
+/**
+ * Parses a filename and returns newly allocated strings with the archive name,
+ * object name, and the object's offset
+ *
+ * @param name The filename of the object
+ * @param aname Address of a string pointer that holds the archive name
+ * @param oname Address of a string pointer that holds the object name
+ * @param ooffset Address of an int that holds the object offset
+ * @retval true The parsing was successful
+ * @retval false The parsing was unsuccessful
+ */
+bool rtems_rtl_parse_name (const char*  name,
+                           const char** aname,
+                           const char** oname,
+                           off_t*       ooffset);
+
+/**
+ * Load the object file.
+ *
+ * @param obj The object file's descriptor.
+ * @param fd The file descriptor.
+ * @param load_syms Load symbols.
+ * @param load_dep Load dependent object files.
+ * @retval true The load was successful.
+ * @retval false The load failed. The RTL error has been set.
+ */
+bool rtems_rtl_obj_file_load (rtems_rtl_obj_t* obj, int fd);
+
+/**
+ * Check of the name matches the object file's object name.
+ *
+ * @param obj The object file's descriptor.
+ * @param name The name to match.
+ */
+bool rtems_rtl_match_name (rtems_rtl_obj_t* obj, const char* name);
+
+/**
+ * Find an object file on disk that matches the name. The object descriptor is
+ * fill in with the various parts of a name. A name can have archive, object
+ * file and offset components. The search path in the RTL is searched.
+ *
+ * @param obj The object file's descriptor.
+ * @param name The name to locate on disk.
+ * @retval true The file has been found.
+ * @retval false The file could not be located. The RTL error has been set.
+ */
+bool rtems_rtl_obj_find_file (rtems_rtl_obj_t* obj, const char* name);
+
+/**
+ * Add a section to the object descriptor.
+ *
+ * @param obj The object file's descriptor.
+ * @param section The section's index number.
+ * @param name The name of the section.
+ * @param size The size of the section in memory.
+ * @param offset The offset of the section in the object file.
+ * @param alignment The alignment of the section in memory.
+ * @param link The section's link field (from the ELF format).
+ * @param info The section's info field (from the ELF format).
+ * @param flags The section's flags.
+ * @retval true The section has been added.
+ * @retval false The section has not been added. See the RTL error.
+ */
+bool rtems_rtl_obj_add_section (rtems_rtl_obj_t* obj,
+                                int              section,
+                                const char*      name,
+                                size_t           size,
+                                off_t            offset,
+                                uint32_t         alignment,
+                                int              link,
+                                int              info,
+                                uint32_t         flags);
+
+/**
+ * Erase the object file descriptor's sections.
+ *
+ * @param obj The object file's descriptor.
+ */
+void rtems_rtl_obj_erase_sections (rtems_rtl_obj_t* obj);
+
+/**
+ * Find the section given a name.
+ *
+ * @param obj The object file's descriptor.
+ * @param name The name of the section to find.
+ * @retval NULL The section was not found.
+ * @return rtems_rtl_obj_sect_t* The named section.
+ */
+rtems_rtl_obj_sect_t* rtems_rtl_obj_find_section (rtems_rtl_obj_t* obj,
+                                                  const char*      name);
+
+/**
+ * Find a section given a section's index number.
+ *
+ * @param obj The object file's descriptor.
+ * @param index The section's index to find.
+ * @retval NULL The section was not found.
+ * @return rtems_rtl_obj_sect_t* The found section.
+ */
+rtems_rtl_obj_sect_t* rtems_rtl_obj_find_section_by_index (rtems_rtl_obj_t* obj,
+                                                           int              index);
+
+/**
+ * The text size of the object file. Only use once all the sections has been
+ * added. It includes alignments between sections that are part of the object's
+ * text area. The consts sections are included in this section.
+ *
+ * @param obj The object file's descriptor.
+ * @return size_t The size of the text area of the object file.
+ */
+size_t rtems_rtl_obj_text_size (rtems_rtl_obj_t* obj);
+
+/**
+ * The text section alignment of the object file. Only use once all the
+ * sections has been added. The section alignment is the alignment of the first
+ * text type section loaded the text section.
+ *
+ * You can assume the alignment is a positive integral power of 2 if not 0 or
+ * 1. If 0 or 1 then there is no alignment.
+ *
+ * @param obj The object file's descriptor.
+ * @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
+ */
+uint32_t rtems_rtl_obj_text_alignment (rtems_rtl_obj_t* obj);
+
+/**
+ * The const size of the object file. Only use once all the sections has been
+ * added. It includes alignments between sections that are part of the object's
+ * const area. The consts sections are included in this section.
+ *
+ * @param obj The object file's descriptor.
+ * @return size_t The size of the const area of the object file.
+ */
+size_t rtems_rtl_obj_const_size (rtems_rtl_obj_t* obj);
+
+/**
+ * The const section alignment of the object file. Only use once all the
+ * sections has been added. The section alignment is the alignment of the first
+ * const type section loaded the const section.
+ *
+ * You can assume the alignment is a positive integral power of 2 if not 0 or
+ * 1. If 0 or 1 then there is no alignment.
+ *
+ * @param obj The object file's descriptor.
+ * @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
+ */
+uint32_t rtems_rtl_obj_const_alignment (rtems_rtl_obj_t* obj);
+
+/**
+ * The data size of the object file. Only use once all the sections has been
+ * added. It includes alignments between sections that are part of the object's
+ * data area.
+ *
+ * @param obj The object file's descriptor.
+ * @return size_t The size of the data area of the object file.
+ */
+size_t rtems_rtl_obj_data_size (rtems_rtl_obj_t* obj);
+
+/**
+ * The data section alignment of the object file. Only use once all the
+ * sections has been added. The section alignment is the alignment of the first
+ * data type section loaded the data section.
+ *
+ * You can assume the alignment is a positive integral power of 2 if not 0 or
+ * 1. If 0 or 1 then there is no alignment.
+ *
+ * @param obj The object file's descriptor.
+ * @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
+ */
+uint32_t rtems_rtl_obj_data_alignment (rtems_rtl_obj_t* obj);
+
+/**
+ * The bss size of the object file. Only use once all the sections has been
+ * added. It includes alignments between sections that are part of the object's
+ * bss area.
+ *
+ * @param obj The object file's descriptor.
+ * @return size_t The size of the bss area of the object file.
+ */
+size_t rtems_rtl_obj_bss_size (rtems_rtl_obj_t* obj);
+
+/**
+ * The bss section alignment of the object file. Only use once all the
+ * sections has been added. The section alignment is the alignment of the first
+ * bss type section loaded the bss section.
+ *
+ * You can assume the alignment is a positive integral power of 2 if not 0 or
+ * 1. If 0 or 1 then there is no alignment.
+ *
+ * @param obj The object file's descriptor.
+ * @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
+ */
+uint32_t rtems_rtl_obj_bss_alignment (rtems_rtl_obj_t* obj);
+
+/**
+ * Relocate the object file. The object file's section are parsed for any
+ * relocation type sections.
+ *
+ * @param obj The object file's descriptor.
+ * @param fd The object file's file descriptor.
+ * @param handler The object file's format specific relocation handler.
+ * @param data User specific data handle.
+ * @retval true The object file was relocated.
+ * @retval false The relocation failed. The RTL error is set.
+ */
+bool rtems_rtl_obj_relocate (rtems_rtl_obj_t*             obj,
+                             int                          fd,
+                             rtems_rtl_obj_sect_handler_t handler,
+                             void*                        data);
+
+/**
+ * Relocate an object file's unresolved reference.
+ *
+ * @param rec The unresolved relocation record.
+ * @param sym The unresolved relocation's referenced symbol.
+ * @retval true The object file record was relocated.
+ * @retval false The relocation failed. The RTL error is set.
+ */
+bool rtems_rtl_obj_relocate_unresolved (rtems_rtl_unresolv_reloc_t* reloc,
+                                        rtems_rtl_obj_sym_t*        sym);
+
+/**
+ * Load the symbols from the object file. Only the exported or public symbols
+ * are read into memory and held in the global symbol table.
+ *
+ * @param obj The object file's descriptor.
+ * @param fd The object file's file descriptor.
+ * @param handler The object file's format specific symbol handler.
+ * @param data User specific data handle.
+ * @retval true The object file's symbol where loaded.
+ * @retval false The symbol loading failed. The RTL error is set.
+ */
+bool rtems_rtl_obj_load_symbols (rtems_rtl_obj_t*             obj,
+                                 int                          fd,
+                                 rtems_rtl_obj_sect_handler_t handler,
+                                 void*                        data);
+
+/**
+ * Load the sections that have been allocated memory in the target. The bss
+ * type section does not load any data, it is set to 0. The text and data
+ * sections read the detault data from the object file into the target memory.
+ *
+ * @param obj The object file's descriptor.
+ * @param fd The object file's file descriptor.
+ * @param handler The object file's format specific load handler.
+ * @param data User specific data handle.
+ * @retval true The object has been sucessfully loaded.
+ * @retval false The load failed. The RTL error has been set.
+ */
+bool rtems_rtl_obj_load_sections (rtems_rtl_obj_t*             obj,
+                                  int                          fd,
+                                  rtems_rtl_obj_sect_handler_t handler,
+                                  void*                        data);
+
+/**
+ * Invoke the constructors the object has. Constructors are a table of pointers
+ * to "void (*)(void);" where NULL pointers are skipped. The table's size is
+ * taken from the section's size. The objet ELF specific code is responisble
+ * for flagging which sections contain constructors.
+ *
+ * @param obj The object file's descriptor.
+ */
+void rtems_rtl_obj_run_ctors (rtems_rtl_obj_t* obj);
+
+/**
+ * Invoke the destructors the object has. Destructors are a table of pointers
+ * to "void (*)(void);" where NULL pointers are skipped. The table's size is
+ * taken from the section's size. The objet ELF specific code is responisble
+ * for flagging which sections contain destructors.
+ *
+ * @param obj The object file's descriptor.
+ */
+void rtems_rtl_obj_run_dtors (rtems_rtl_obj_t* obj);
+
+/**
+ * Load the object file, reading all sections into memory, symbols and
+ * performing any relocation fixups.
+ *
+ * @param obj The object file's descriptor.
+ * @retval true The object file has been loaded.
+ * @retval false The load failed. The RTL error has been set.
+ */
+bool rtems_rtl_obj_load (rtems_rtl_obj_t* obj);
+
+/**
+ * Unload the object file, erasing all symbols and releasing all memory.
+ *
+ * @param obj The object file's descriptor.
+ * @retval true The object file has been unloaded.
+ * @retval false The unload failed. The RTL error has been set.
+ */
+bool rtems_rtl_obj_unload (rtems_rtl_obj_t* obj);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/libdl/rtl-rap.c b/cpukit/libdl/rtl-rap.c
new file mode 100644
index 0000000..ad05b24
--- /dev/null
+++ b/cpukit/libdl/rtl-rap.c
@@ -0,0 +1,980 @@
+/*
+ *  COPYRIGHT (c) 2012-2013 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtld
+ *
+ * @brief RTEMS Run-Time Link Editor
+ *
+ * This is the RAP format loader support..
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-elf.h"
+#include "rtl-error.h"
+#include "rtl-obj-comp.h"
+#include "rtl-rap.h"
+#include "rtl-trace.h"
+#include "rtl-unresolved.h"
+
+/**
+ * The offsets in the unresolved array.
+ */
+#define REL_R_OFFSET (0)
+#define REL_R_INFO   (1)
+#define REL_R_ADDEND (2)
+
+/**
+ * The ELF format signature.
+ */
+static rtems_rtl_loader_format_t rap_sig =
+{
+  .label = "RAP",
+  .flags = RTEMS_RTL_FMT_COMP
+};
+
+/**
+ * The section definitions found in a RAP file.
+ */
+typedef struct rtems_rtl_rap_sectdef_s
+{
+  const char*    name;    /**< Name of the section. */
+  const uint32_t flags;   /**< Section flags. */
+} rtems_rtl_rap_sectdef_t;
+
+/**
+ * The section indexes. These are fixed.
+ */
+#define RTEMS_RTL_RAP_TEXT_SEC  (0)
+#define RTEMS_RTL_RAP_CONST_SEC (1)
+#define RTEMS_RTL_RAP_CTOR_SEC  (2)
+#define RTEMS_RTL_RAP_DTOR_SEC  (3)
+#define RTEMS_RTL_RAP_DATA_SEC  (4)
+#define RTEMS_RTL_RAP_BSS_SEC   (5)
+#define RTEMS_RTL_RAP_SECS      (6)
+
+/**
+ * The sections as loaded from a RAP file.
+ */
+static const rtems_rtl_rap_sectdef_t rap_sections[RTEMS_RTL_RAP_SECS] =
+{
+  { ".text",  RTEMS_RTL_OBJ_SECT_TEXT  | RTEMS_RTL_OBJ_SECT_LOAD },
+  { ".const", RTEMS_RTL_OBJ_SECT_CONST | RTEMS_RTL_OBJ_SECT_LOAD },
+  { ".ctor",  RTEMS_RTL_OBJ_SECT_CONST | RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_CTOR },
+  { ".dtor",  RTEMS_RTL_OBJ_SECT_CONST | RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_DTOR },
+  { ".data",  RTEMS_RTL_OBJ_SECT_DATA  | RTEMS_RTL_OBJ_SECT_LOAD },
+  { ".bss",   RTEMS_RTL_OBJ_SECT_BSS   | RTEMS_RTL_OBJ_SECT_ZERO }
+};
+
+/**
+ * The section definitions found in a RAP file.
+ */
+typedef struct rtems_rtl_rap_section_s
+{
+  uint32_t size;       /**< The size of the section. */
+  uint32_t alignment;  /**< The alignment of the section. */
+} rtems_rtl_rap_section_t;
+
+/**
+ * The RAP loader.
+ */
+typedef struct rtems_rtl_rap_s
+{
+  rtems_rtl_obj_cache_t*  file;         /**< The file cache for the RAP file. */
+  rtems_rtl_obj_comp_t*   decomp;       /**< The decompression streamer. */
+  uint32_t                length;       /**< The file length. */
+  uint32_t                version;      /**< The RAP file version. */
+  uint32_t                compression;  /**< The type of compression. */
+  uint32_t                checksum;     /**< The checksum. */
+  uint32_t                machinetype;  /**< The ELF machine type. */
+  uint32_t                datatype;     /**< The ELF data type. */
+  uint32_t                class;        /**< The ELF class. */
+  uint32_t                init;         /**< The initialisation strtab offset. */
+  uint32_t                fini;         /**< The finish strtab offset. */
+  rtems_rtl_rap_section_t secs[RTEMS_RTL_RAP_SECS]; /**< The sections. */
+  uint32_t                symtab_size;  /**< The symbol table size. */
+  char*                   strtab;       /**< The string table. */
+  uint32_t                strtab_size;  /**< The string table size. */
+  uint32_t                relocs_size;  /**< The relocation table size. */
+  uint32_t                symbols;      /**< The number of symbols. */
+  uint32_t                strtable_size;/**< The size of section names and obj names. */
+  uint32_t                rpathlen;     /**< The length of rpath. */
+  char*                   strtable;     /**< The detail string which resides in obj detail. */
+} rtems_rtl_rap_t;
+
+/**
+ * Check the machine type.
+ */
+static bool
+rtems_rtl_rap_machine_check (uint32_t machinetype)
+{
+  /*
+   * This code is determined by the machine headers.
+   */
+  switch (machinetype)
+  {
+    ELFDEFNNAME (MACHDEP_ID_CASES)
+    default:
+      return false;
+  }
+  return true;
+}
+
+/**
+ * Check the data type.
+ */
+static bool
+rtems_rtl_rap_datatype_check (uint32_t datatype)
+{
+  /*
+   * This code is determined by the machine headers.
+   */
+  if (datatype != ELFDEFNNAME (MACHDEP_ENDIANNESS))
+    return false;
+  return true;
+}
+
+/**
+ * Check the class of executable.
+ */
+static bool
+rtems_rtl_rap_class_check (uint32_t class)
+{
+  /*
+   * This code is determined by the machine headers.
+   */
+  switch (class)
+  {
+    case ELFCLASS32:
+      if (ARCH_ELFSIZE == 32)
+        return true;
+      break;
+    case ELFCLASS64:
+      if (ARCH_ELFSIZE == 64)
+        return true;
+      break;
+    default:
+      break;
+  }
+  return false;
+}
+
+static uint32_t
+rtems_rtl_rap_get_uint32 (const uint8_t* buffer)
+{
+  uint32_t value = 0;
+  int      b;
+  for (b = 0; b < sizeof (uint32_t); ++b)
+  {
+    value <<= 8;
+    value |= buffer[b];
+  }
+  return value;
+}
+
+static bool
+rtems_rtl_rap_read_uint32 (rtems_rtl_obj_comp_t* comp, uint32_t* value)
+{
+  uint8_t buffer[sizeof (uint32_t)];
+
+  if (!rtems_rtl_obj_comp_read (comp, buffer, sizeof (uint32_t)))
+    return false;
+
+  *value = rtems_rtl_rap_get_uint32 (buffer);
+
+  return true;
+}
+
+static bool
+rtems_rtl_rap_loader (rtems_rtl_obj_t*      obj,
+                      int                   fd,
+                      rtems_rtl_obj_sect_t* sect,
+                      void*                 data)
+{
+  rtems_rtl_rap_t* rap = (rtems_rtl_rap_t*) data;
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
+    printf ("rtl: rap: input %s=%lu\n",
+            sect->name, rtems_rtl_obj_comp_input (rap->decomp));
+
+  return rtems_rtl_obj_comp_read (rap->decomp, sect->base, sect->size);
+}
+
+static bool
+rtems_rtl_rap_relocate (rtems_rtl_rap_t* rap, rtems_rtl_obj_t* obj)
+{
+  #define SYMNAME_BUFFER_SIZE (1024)
+  char*    symname_buffer = NULL;
+  int      section;
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+    printf ("rtl: relocation\n");
+
+  symname_buffer = malloc (SYMNAME_BUFFER_SIZE);
+  if (!symname_buffer)
+  {
+    rtems_rtl_set_error (ENOMEM, "no memory for local symbol name buffer");
+    return false;
+  }
+
+  for (section = 0; section < RTEMS_RTL_RAP_SECS; ++section)
+  {
+    rtems_rtl_obj_sect_t*  targetsect;
+    uint32_t               header = 0;
+    int                    relocs;
+    bool                   is_rela;
+    int                    r;
+
+    targetsect = rtems_rtl_obj_find_section (obj, rap_sections[section].name);
+
+    if (!targetsect)
+    {
+      rtems_rtl_set_error (EINVAL, "no target section found");
+      free (symname_buffer);
+      return false;
+    }
+
+    if (!rtems_rtl_rap_read_uint32 (rap->decomp, &header))
+    {
+      free (symname_buffer);
+      return false;
+    }
+
+    /*
+     * Bit 31 of the header indicates if the relocations for this section
+     * have a valid addend field.
+     */
+
+    is_rela = (header & (1 << 31)) != 0 ? true : false;
+    relocs = header & ~(1 << 31);
+
+    if (relocs && rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+      printf ("rtl: relocation: %s: header: %08lx relocs: %d %s\n",
+              rap_sections[section].name,
+              header, relocs, is_rela ? "rela" : "rel");
+
+    for (r = 0; r < relocs; ++r)
+    {
+      uint32_t    info = 0;
+      uint32_t    offset = 0;
+      uint32_t    addend = 0;
+      Elf_Word    type;
+      const char* symname = NULL;
+      uint32_t    symname_size;
+      Elf_Word    symtype = 0;
+      Elf_Word    symvalue = 0;
+
+      if (!rtems_rtl_rap_read_uint32 (rap->decomp, &info))
+      {
+        free (symname_buffer);
+        return false;
+      }
+
+      if (!rtems_rtl_rap_read_uint32 (rap->decomp, &offset))
+      {
+        free (symname_buffer);
+        return false;
+      }
+
+      /*
+       * The types are:
+       *
+       *  0  Section symbol offset in addend.
+       *  1  Symbol appended to the relocation record.
+       *  2  Symbol is in the strtabl.
+       *
+       * If type 2 bits 30:8 is the offset in the strtab. If type 1 the bits
+       * are the size of the string. The lower 8 bits of the info field if the
+       * ELF relocation type field.
+       */
+
+      if (((info & (1 << 31)) == 0) || is_rela)
+      {
+        if (!rtems_rtl_rap_read_uint32 (rap->decomp, &addend))
+        {
+          free (symname_buffer);
+          return false;
+        }
+      }
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf (" %2d: info=%08lx offset=%lu addend=%lu\n",
+                r, info, offset, addend);
+
+      type = info & 0xff;
+
+      if ((info & (1 << 31)) == 0)
+      {
+        rtems_rtl_obj_sect_t* symsect;
+
+        symsect = rtems_rtl_obj_find_section_by_index (obj, info >> 8);
+        if (!symsect)
+        {
+          free (symname_buffer);
+          return false;
+        }
+
+        symvalue = (Elf_Word) symsect->base + addend;
+      }
+      else if (rtems_rtl_elf_rel_resolve_sym (type))
+      {
+        rtems_rtl_obj_sym_t* symbol;
+
+        symname_size = (info & ~(3 << 30)) >> 8;
+
+        if ((info & (1 << 30)) != 0)
+        {
+          symname = rap->strtab + symname_size;
+        }
+        else
+        {
+          if (symname_size > (SYMNAME_BUFFER_SIZE - 1))
+          {
+            free (symname_buffer);
+            rtems_rtl_set_error (EINVAL, "reloc symbol too big");
+            return false;
+          }
+
+          if (!rtems_rtl_obj_comp_read (rap->decomp, symname_buffer, symname_size))
+          {
+            free (symname_buffer);
+            return false;
+          }
+
+          symname_buffer[symname_size] = '\0';
+          symname = symname_buffer;
+        }
+
+        symbol = rtems_rtl_symbol_obj_find (obj, symname);
+
+        if (!symbol)
+        {
+          rtems_rtl_set_error (EINVAL, "global symbol not found: %s", symname);
+          free (symname_buffer);
+          return false;
+        }
+
+        symvalue = (Elf_Word) symbol->value;
+      }
+
+      if (is_rela)
+      {
+        Elf_Rela rela;
+
+        rela.r_offset = offset;
+        rela.r_info = type;
+
+        if ((info & (1 << 31)) == 0)
+          rela.r_addend = 0;
+        else rela.r_addend = addend;
+
+        if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+          printf (" %2d: rela: type:%-2d off:%lu addend:%d" \
+                  " symname=%s symtype=%lu symvalue=0x%08lx\n",
+                  r, (int) type, offset, (int) addend,
+                  symname, symtype, symvalue);
+
+        if (!rtems_rtl_elf_relocate_rela (obj, &rela, targetsect,
+                                          symname, symtype, symvalue))
+        {
+          free (symname_buffer);
+          return false;
+        }
+      }
+      else
+      {
+        Elf_Rel rel;
+
+        rel.r_offset = offset;
+        rel.r_info = type;
+
+        if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+          printf (" %2d: rel: type:%-2d off:%lu" \
+                  " symname=%s symtype=%lu symvalue=0x%08lx\n",
+                  r, (int) type, offset,
+                  symname, symtype, symvalue);
+
+        if (!rtems_rtl_elf_relocate_rel (obj, &rel, targetsect,
+                                         symname, symtype, symvalue))
+        {
+          free (symname_buffer);
+          return false;
+        }
+      }
+    }
+  }
+
+  free (symname_buffer);
+
+  return true;
+}
+
+/**
+ * The structure of obj->detail is
+ *
+ * |object_detail(0..obj_num)|section_detail(0..sec_num[0..obj_num])|
+ * obj_name(0..obj_num)|section_name(0..sec_num[0..obj_num])
+ *
+ */
+static bool
+rtems_rtl_rap_load_details (rtems_rtl_rap_t* rap, rtems_rtl_obj_t* obj)
+{
+  struct link_map* tmp1;
+  section_detail* tmp2;
+  uint32_t obj_detail_size;
+  uint32_t pos = 0;
+  int i,j;
+
+  obj_detail_size = sizeof (struct link_map) * obj->obj_num;
+
+  for (i = 0; i < obj->obj_num; ++i)
+  {
+    obj_detail_size += (obj->sec_num[i] * sizeof (section_detail));
+  }
+
+  obj->detail = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
+                                     obj_detail_size + rap->strtable_size, true);
+
+  if (!obj->detail)
+  {
+    rap->strtable_size = 0;
+    rtems_rtl_set_error (ENOMEM, "no memory for obj global syms");
+    return false;
+  }
+
+  rap->strtable = obj->detail + obj_detail_size;
+
+  /* Read the obj names and section names */
+  if (!rtems_rtl_obj_comp_read (rap->decomp, rap->strtable,
+                                rap->strtable_size))
+  {
+    rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, obj->detail);
+    return false;
+  }
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
+  {
+    if (rap->rpathlen > 0)
+      printf ("File rpath:\n");
+  }
+
+  while (pos < rap->rpathlen)
+  {
+    if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
+    {
+      printf ("          %s\n", rap->strtable + pos);
+    }
+    pos = pos + strlen (rap->strtable + pos) + 1;
+  }
+
+  if (rap->rpathlen > 0)
+    pos = rap->rpathlen;
+
+  for (i = 0; i < obj->obj_num; ++i)
+  {
+    tmp1 = (struct link_map*) (obj->detail) + i;
+    tmp1->name = rap->strtable + pos;
+    tmp1->sec_num = obj->sec_num[i];
+    tmp1->rpathlen = rap->rpathlen;
+    tmp1->rpath = (char*) rap->strtable;
+    pos += strlen (tmp1->name) + 1;
+
+    if (!i)
+    {
+      tmp1->l_next = NULL;
+      tmp1->l_prev = NULL;
+    }
+    else
+    {
+      (tmp1 - 1)->l_next = tmp1;
+      tmp1->l_prev = tmp1 - 1;
+      tmp1->l_next = NULL;
+    }
+  }
+
+  tmp2 =(section_detail*) ((struct link_map*) (obj->detail) + obj->obj_num);
+
+  for (i = 0; i < obj->obj_num; ++i)
+  {
+    if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
+    {
+      printf ("File %d: %s\n", i, ((struct link_map*) obj->detail + i)->name);
+      printf ("Section: %d sections\n",(unsigned int) obj->sec_num[i]);
+    }
+
+    ((struct link_map*)obj->detail + i)->sec_detail = tmp2;
+
+    for (j = 0; j < obj->sec_num[i]; ++j)
+    {
+      uint32_t name;
+      uint32_t rap_id;
+      uint32_t offset;
+      uint32_t size;
+
+      if (!rtems_rtl_rap_read_uint32 (rap->decomp, &name) ||
+          !rtems_rtl_rap_read_uint32 (rap->decomp, &offset) ||
+          !rtems_rtl_rap_read_uint32 (rap->decomp, &size))
+      {
+        rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_SYMBOL, obj->detail);
+        return false;
+      }
+
+      rap_id = offset >> 28;
+      offset = offset & 0xfffffff;
+
+      tmp2->name = rap->strtable + name;
+      tmp2->offset = offset;
+      tmp2->rap_id = rap_id;
+      tmp2->size = size;
+      pos += strlen (tmp2->name) + 1;
+
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
+      {
+        printf ("name:%16s offset:0x%08x rap_id:%d size:0x%x\n",
+                tmp2->name, (unsigned int) tmp2->offset,
+                (unsigned int) tmp2->rap_id, (unsigned int) tmp2->size);
+      }
+
+      tmp2 += 1;
+    }
+  }
+  return true;
+}
+
+static bool
+rtems_rtl_rap_load_symbols (rtems_rtl_rap_t* rap, rtems_rtl_obj_t* obj)
+{
+  rtems_rtl_obj_sym_t* gsym;
+  int                  sym;
+
+  obj->global_size =
+    rap->symbols * sizeof (rtems_rtl_obj_sym_t) + rap->strtab_size;
+
+  obj->global_table = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_SYMBOL,
+                                           obj->global_size, true);
+  if (!obj->global_table)
+  {
+    obj->global_size = 0;
+    rtems_rtl_set_error (ENOMEM, "no memory for obj global syms");
+    return false;
+  }
+
+  obj->global_syms = rap->symbols;
+
+  rap->strtab = (((char*) obj->global_table) +
+                 (rap->symbols * sizeof (rtems_rtl_obj_sym_t)));
+
+  if (!rtems_rtl_obj_comp_read (rap->decomp, rap->strtab, rap->strtab_size))
+    return false;
+
+  for (sym = 0, gsym = obj->global_table; sym < rap->symbols; ++sym)
+  {
+    rtems_rtl_obj_sect_t* symsect;
+    uint32_t              data;
+    uint32_t              name;
+    uint32_t              value;
+
+    if (!rtems_rtl_rap_read_uint32 (rap->decomp, &data) ||
+        !rtems_rtl_rap_read_uint32 (rap->decomp, &name) ||
+        !rtems_rtl_rap_read_uint32 (rap->decomp, &value))
+    {
+      free (obj->global_table);
+      obj->global_table = NULL;
+      obj->global_syms = 0;
+      obj->global_size = 0;
+      return false;
+    }
+
+    if (rtems_rtl_trace (RTEMS_RTL_TRACE_SYMBOL))
+      printf ("rtl: sym:load: data=0x%08lx name=0x%08lx value=0x%08lx\n",
+              data, name, value);
+
+    /*
+     * If there is a globally exported symbol already present and this
+     * symbol is not weak raise an error. If the symbol is weak and present
+     * globally ignore this symbol and use the global one and if it is not
+     * present take this symbol global or weak. We accept the first weak
+     * symbol we find and make it globally exported.
+     */
+    if (rtems_rtl_symbol_global_find (rap->strtab + name) &&
+        (ELF_ST_BIND (data & 0xffff) != STB_WEAK))
+    {
+      rtems_rtl_set_error (EINVAL,
+                           "duplicate global symbol: %s", rap->strtab + name);
+      free (obj->global_table);
+      obj->global_table = NULL;
+      obj->global_syms = 0;
+      obj->global_size = 0;
+      return false;
+    }
+
+    symsect = rtems_rtl_obj_find_section_by_index (obj, data >> 16);
+    if (!symsect)
+    {
+      free (obj->global_table);
+      obj->global_table = NULL;
+      obj->global_syms = 0;
+      obj->global_size = 0;
+      rtems_rtl_set_error (EINVAL, "section index not found: %lu", data >> 16);
+      return false;
+    }
+
+    rtems_chain_set_off_chain (&gsym->node);
+    gsym->name = rap->strtab + name;
+    gsym->value = (uint8_t*) (value + symsect->base);
+    gsym->data = data & 0xffff;
+
+    if (rtems_rtl_trace (RTEMS_RTL_TRACE_SYMBOL))
+      printf ("rtl: sym:add:%-2d name:%-20s bind:%-2d type:%-2d val:%8p sect:%d\n",
+              sym, gsym->name,
+              (int) ELF_ST_BIND (data & 0xffff),
+              (int) ELF_ST_TYPE (data & 0xffff),
+              gsym->value, (int) (data >> 16));
+
+    ++gsym;
+  }
+
+  return true;
+}
+
+static bool
+rtems_rtl_rap_parse_header (uint8_t*  rhdr,
+                            size_t*   rhdr_len,
+                            uint32_t* length,
+                            uint32_t* version,
+                            uint32_t* compression,
+                            uint32_t* checksum)
+{
+  char* sptr = (char*) rhdr;
+  char* eptr;
+
+  *rhdr_len = 0;
+
+  /*
+   * "RAP," = 4 bytes, total 4
+   */
+
+  if ((rhdr[0] != 'R') || (rhdr[1] != 'A') || (rhdr[2] != 'P') || (rhdr[3] != ','))
+    return false;
+
+  sptr = sptr + 4;
+
+  /*
+   * "00000000," = 9 bytes, total 13
+   */
+
+  *length = strtoul (sptr, &eptr, 10);
+
+  if (*eptr != ',')
+    return false;
+
+  sptr = eptr + 1;
+
+  /*
+   * "0000," = 5 bytes, total 18
+   */
+
+  *version = strtoul (sptr, &eptr, 10);
+
+  if (*eptr != ',')
+    return false;
+
+  sptr = eptr + 1;
+
+  /*
+   * "NONE," and "LZ77," = 5 bytes, total 23
+   */
+
+  if ((sptr[0] == 'N') &&
+      (sptr[1] == 'O') &&
+      (sptr[2] == 'N') &&
+      (sptr[3] == 'E'))
+  {
+    *compression = RTEMS_RTL_COMP_NONE;
+    eptr = sptr + 4;
+  }
+  else if ((sptr[0] == 'L') &&
+           (sptr[1] == 'Z') &&
+           (sptr[2] == '7') &&
+           (sptr[3] == '7'))
+  {
+    *compression = RTEMS_RTL_COMP_LZ77;
+    eptr = sptr + 4;
+  }
+  else
+    return false;
+
+  if (*eptr != ',')
+    return false;
+
+  sptr = eptr + 1;
+
+  /*
+   * "00000000," = 9 bytes, total 32
+   */
+  *checksum = strtoul (sptr, &eptr, 16);
+
+  /*
+   * "\n" = 1 byte, total 33
+   */
+  if (*eptr != '\n')
+    return false;
+
+  *rhdr_len = ((uint8_t*) eptr) - rhdr + 1;
+
+  return true;
+}
+
+bool
+rtems_rtl_rap_file_check (rtems_rtl_obj_t* obj, int fd)
+{
+  rtems_rtl_obj_cache_t* header;
+  uint8_t*               rhdr = NULL;
+  size_t                 rlen = 64;
+  uint32_t               length = 0;
+  uint32_t               version = 0;
+  uint32_t               compression = 0;
+  uint32_t               checksum = 0;
+
+  rtems_rtl_obj_caches (&header, NULL, NULL);
+
+  if (!rtems_rtl_obj_cache_read (header, fd, obj->ooffset,
+                                 (void**) &rhdr, &rlen))
+    return false;
+
+  if (!rtems_rtl_rap_parse_header (rhdr,
+                                   &rlen,
+                                   &length,
+                                   &version,
+                                   &compression,
+                                   &checksum))
+    return false;
+
+  return true;
+}
+
+bool
+rtems_rtl_rap_file_load (rtems_rtl_obj_t* obj, int fd)
+{
+  rtems_rtl_rap_t rap = { 0 };
+  uint8_t*        rhdr = NULL;
+  size_t          rlen = 64;
+  int             section;
+
+  rtems_rtl_obj_caches (&rap.file, NULL, NULL);
+
+  if (!rtems_rtl_obj_cache_read (rap.file, fd, obj->ooffset,
+                                 (void**) &rhdr, &rlen))
+    return false;
+
+  if (!rtems_rtl_rap_parse_header (rhdr,
+                                   &rlen,
+                                   &rap.length,
+                                   &rap.version,
+                                   &rap.compression,
+                                   &rap.checksum))
+  {
+    rtems_rtl_set_error (EINVAL, "invalid RAP file format");
+    return false;
+  }
+
+  /*
+   * Set up the decompressor.
+   */
+  rtems_rtl_obj_comp (&rap.decomp, rap.file, fd, rap.compression,
+                      rlen + obj->ooffset);
+
+  /*
+   * uint32_t: machinetype
+   * uint32_t: datatype
+   * uint32_t: class
+   */
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
+    printf ("rtl: rap: input machine=%lu\n",
+            rtems_rtl_obj_comp_input (rap.decomp));
+
+  if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.machinetype))
+    return false;
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
+    printf ("rtl: rap: machinetype=%lu\n", rap.machinetype);
+
+  if (!rtems_rtl_rap_machine_check (rap.machinetype))
+  {
+    rtems_rtl_set_error (EINVAL, "invalid machinetype");
+    return false;
+  }
+
+  if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.datatype))
+    return false;
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
+    printf ("rtl: rap: datatype=%lu\n", rap.datatype);
+
+  if (!rtems_rtl_rap_datatype_check (rap.datatype))
+  {
+    rtems_rtl_set_error (EINVAL, "invalid datatype");
+    return false;
+  }
+
+  if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.class))
+    return false;
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
+    printf ("rtl: rap: class=%lu\n", rap.class);
+
+  if (!rtems_rtl_rap_class_check (rap.class))
+  {
+    rtems_rtl_set_error (EINVAL, "invalid class");
+    return false;
+  }
+
+  /*
+   * uint32_t: init
+   * uint32_t: fini
+   * uint32_t: symtab_size
+   * uint32_t: strtab_size
+   * uint32_t: relocs_size
+   */
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
+    printf ("rtl: rap: input header=%lu\n",
+            rtems_rtl_obj_comp_input (rap.decomp));
+
+  if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.init))
+    return false;
+
+  if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.fini))
+    return false;
+
+  if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.symtab_size))
+    return false;
+
+  if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.strtab_size))
+    return false;
+
+  if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.relocs_size))
+    return false;
+
+  rap.symbols = rap.symtab_size / (3 * sizeof (uint32_t));
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
+    printf ("rtl: rap: load: symtab=%lu (%lu) strtab=%lu relocs=%lu\n",
+            rap.symtab_size, rap.symbols,
+            rap.strtab_size, rap.relocs_size);
+
+  /*
+   * Load the details
+   */
+  if (!rtems_rtl_rap_read_uint32 (rap.decomp, &obj->obj_num))
+    return false;
+
+  if (obj->obj_num > 0)
+  {
+    obj->sec_num = (uint32_t*) malloc (sizeof (uint32_t) * obj->obj_num);
+
+    if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.rpathlen))
+      return false;
+
+    uint32_t i;
+    for (i = 0; i < obj->obj_num; ++i)
+    {
+      if (!rtems_rtl_rap_read_uint32 (rap.decomp, &(obj->sec_num[i])))
+        return false;
+    }
+
+    if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.strtable_size))
+      return false;
+
+    if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
+      printf ("rtl: rap: details: obj_num=%lu\n", obj->obj_num);
+
+    if (!rtems_rtl_rap_load_details (&rap, obj))
+      return false;
+  }
+
+  /*
+   * uint32_t: text_size
+   * uint32_t: text_alignment
+   * uint32_t: const_size
+   * uint32_t: const_alignment
+   * uint32_t: ctor_size
+   * uint32_t: ctor_alignment
+   * uint32_t: dtor_size
+   * uint32_t: dtor_alignment
+   * uint32_t: data_size
+   * uint32_t: data_alignment
+   * uint32_t: bss_size
+   * uint32_t: bss_alignment
+   */
+
+  for (section = 0; section < RTEMS_RTL_RAP_SECS; ++section)
+  {
+    if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.secs[section].size))
+      return false;
+
+    if (!rtems_rtl_rap_read_uint32 (rap.decomp, &rap.secs[section].alignment))
+      return false;
+
+    if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
+      printf ("rtl: rap: %s: size=%lu align=%lu\n",
+              rap_sections[section].name,
+              rap.secs[section].size,
+              rap.secs[section].alignment);
+
+    if (!rtems_rtl_obj_add_section (obj,
+                                    section,
+                                    rap_sections[section].name,
+                                    rap.secs[section].size,
+                                    0,
+                                    rap.secs[section].alignment,
+                                    0, 0,
+                                    rap_sections[section].flags))
+      return false;
+  }
+
+  /** obj->entry = (void*)(uintptr_t) ehdr.e_entry; */
+
+  if (!rtems_rtl_obj_load_sections (obj, fd, rtems_rtl_rap_loader, &rap))
+    return false;
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
+    printf ("rtl: rap: input symbols=%lu\n",
+            rtems_rtl_obj_comp_input (rap.decomp));
+
+  if (!rtems_rtl_rap_load_symbols (&rap, obj))
+    return false;
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
+    printf ("rtl: rap: input relocs=%lu\n",
+            rtems_rtl_obj_comp_input (rap.decomp));
+
+  if (!rtems_rtl_rap_relocate (&rap, obj))
+    return false;
+
+  return true;
+}
+
+rtems_rtl_loader_format_t*
+rtems_rtl_rap_file_sig (void)
+{
+  return &rap_sig;
+}
diff --git a/cpukit/libdl/rtl-rap.h b/cpukit/libdl/rtl-rap.h
new file mode 100644
index 0000000..54c1268
--- /dev/null
+++ b/cpukit/libdl/rtl-rap.h
@@ -0,0 +1,54 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker ELF Headers
+ */
+
+#if !defined (_RTEMS_RTL_RAP_H_)
+#define _RTEMS_RTL_RAP_H_
+
+#include "rtl-fwd.h"
+#include "rtl-obj-fwd.h"
+#include "rtl-sym.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * The RAP format check handler.
+ *
+ * @param obj The object being checked.
+ * @param fd The file descriptor.
+ */
+bool rtems_rtl_rap_file_check (rtems_rtl_obj_t* obj, int fd);
+
+/**
+ * The RAP format load handler.
+ *
+ * @param obj The object to load.
+ * @param fd The file descriptor.
+ */
+bool rtems_rtl_rap_file_load (rtems_rtl_obj_t* obj, int fd);
+
+/**
+ * The RAP format signature handler.
+ *
+ * @return rtems_rtl_loader_format_t* The format's signature.
+ */
+rtems_rtl_loader_format_t* rtems_rtl_rap_file_sig (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/libdl/rtl-shell.c b/cpukit/libdl/rtl-shell.c
new file mode 100644
index 0000000..0e33e84
--- /dev/null
+++ b/cpukit/libdl/rtl-shell.c
@@ -0,0 +1,389 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtld
+ *
+ * @brief RTEMS Run-Time Link Editor Shell Commands
+ *
+ * A simple RTL command to aid using the RTL.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <inttypes.h>
+
+//#if SIZEOF_OFF_T == 8
+#define PRIdoff_t PRIo64
+//#elif SIZEOF_OFF_T == 4
+//#define PRIdoff_t PRIo32
+//#else
+//#error "unsupported size of off_t"
+//#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-chain-iterator.h"
+#include "rtl-shell.h"
+#include "rtl-trace.h"
+
+/**
+ * The type of the shell handlers we have.
+ */
+typedef int (*rtems_rtl_shell_handler_t) (rtems_rtl_data_t* rtl, int argc, char *argv[]);
+
+/**
+ * Table of handlers we parse to invoke the command.
+ */
+typedef struct
+{
+  const char*               name;    /**< The sub-command's name. */
+  rtems_rtl_shell_handler_t handler; /**< The sub-command's handler. */
+  const char*               help;    /**< The sub-command's help. */
+} rtems_rtl_shell_cmd_t;
+
+/**
+ * Object summary data.
+ */
+typedef struct
+{
+  int    count;   /**< The number of object files. */
+  size_t exec;    /**< The amount of executable memory allocated. */
+  size_t symbols; /**< The amount of symbol memory allocated. */
+} rtems_rtl_obj_summary_t;
+
+/**
+ * Object summary iterator.
+ */
+static bool
+rtems_rtl_obj_summary_iterator (rtems_chain_node* node, void* data)
+{
+  rtems_rtl_obj_summary_t* summary = data;
+  rtems_rtl_obj_t*         obj = (rtems_rtl_obj_t*) node;
+  ++summary->count;
+  summary->exec += obj->exec_size;
+  summary->symbols += obj->global_size;
+  return true;
+}
+
+/**
+ * Count the number of symbols.
+ */
+static int
+rtems_rtl_count_symbols (rtems_rtl_data_t* rtl)
+{
+  int count;
+  int bucket;
+  for (count = 0, bucket = 0; bucket < rtl->globals.nbuckets; ++bucket)
+    count += rtems_rtl_chain_count (&rtl->globals.buckets[bucket]);
+  return count;
+}
+
+static int
+rtems_rtl_shell_status (rtems_rtl_data_t* rtl, int argc, char *argv[])
+{
+  rtems_rtl_obj_summary_t summary;
+  size_t                  total_memory;
+
+  summary.count   = 0;
+  summary.exec    = 0;
+  summary.symbols = 0;
+  rtems_rtl_chain_iterate (&rtl->objects,
+                           rtems_rtl_obj_summary_iterator,
+                           &summary);
+  /*
+   * Currently does not include the name strings in the obj struct.
+   */
+  total_memory =
+    sizeof (*rtl) + (summary.count * sizeof (rtems_rtl_obj_t)) +
+    summary.exec + summary.symbols;
+
+  printf ("Runtime Linker Status:\n");
+  printf ("        paths: %s\n", rtl->paths);
+  printf ("      objects: %d\n", summary.count);
+  printf (" total memory: %zi\n", total_memory);
+  printf ("  exec memory: %zi\n", summary.exec);
+  printf ("   sym memory: %zi\n", summary.symbols);
+  printf ("      symbols: %d\n", rtems_rtl_count_symbols (rtl));
+
+  return 0;
+}
+
+/**
+ * Object print data.
+ */
+typedef struct
+{
+  rtems_rtl_data_t* rtl; /**< The RTL data. */
+  int  indent;           /**< Spaces to indent. */
+  bool oname;            /**< Print object names. */
+  bool names;            /**< Print details of all names. */
+  bool memory_map;       /**< Print the memory map. */
+  bool symbols;          /**< Print the global symbols. */
+  bool base;             /**< Include the base object file. */
+} rtems_rtl_obj_print_t;
+
+/**
+ * Return the different between 2 void*.
+ */
+static size_t
+rtems_rtl_delta_voids (void* higher, void* lower)
+{
+  char* ch = higher;
+  char* cl = lower;
+  return ch - cl;
+}
+
+/**
+ * Parse an argument.
+ */
+static bool
+rtems_rtl_parse_arg (const char* opt, int argc, char *argv[])
+{
+  int arg;
+  for (arg = 0; arg < argc; ++arg)
+    if (strncmp (opt, argv[arg], 2) == 0)
+      return true;
+  return false;
+}
+
+/**
+ * See if -b for base is set.
+ */
+static bool
+rtems_rtl_base_arg (int argc, char *argv[])
+{
+  return rtems_rtl_parse_arg ("-b", argc, argv);
+}
+
+/**
+ * See if -s for base is set.
+ */
+static bool
+rtems_rtl_symbols_arg (int argc, char *argv[])
+{
+  return rtems_rtl_parse_arg ("-s", argc, argv);
+}
+
+/**
+ * Object printer.
+ */
+static bool
+rtems_rtl_obj_printer (rtems_rtl_obj_print_t* print, rtems_rtl_obj_t* obj)
+{
+  char flags_str[33];
+
+  /*
+   * Skip the base module unless asked to show it.
+   */
+  if (!print->base && (obj == print->rtl->base))
+      return true;
+
+  if (print->oname)
+  {
+    printf ("%-*cobject name   : %s\n",
+            print->indent, ' ', rtems_rtl_obj_oname (obj));
+  }
+  if (print->names)
+  {
+    printf ("%-*cfile name     : %s\n",
+            print->indent, ' ', rtems_rtl_obj_fname (obj));
+    printf ("%-*carchive name  : %s\n",
+            print->indent, ' ', rtems_rtl_obj_aname (obj));
+    strcpy (flags_str, "--");
+    if (obj->flags & RTEMS_RTL_OBJ_LOCKED)
+      flags_str[0] = 'L';
+    if (obj->flags & RTEMS_RTL_OBJ_UNRESOLVED)
+      flags_str[1] = 'U';
+    printf ("%-*cflags         : %s\n", print->indent, ' ', flags_str);
+    printf ("%-*cfile offset   : %" PRIdoff_t "\n", print->indent, ' ', obj->ooffset);
+    printf ("%-*cfile size     : %zi\n", print->indent, ' ', obj->fsize);
+  }
+  if (print->memory_map)
+  {
+    printf ("%-*cexec size     : %zi\n", print->indent, ' ', obj->exec_size);
+    printf ("%-*ctext base     : %p (%zi)\n", print->indent, ' ',
+            obj->text_base, rtems_rtl_delta_voids (obj->const_base, obj->text_base));
+    printf ("%-*cconst base    : %p (%zi)\n", print->indent, ' ',
+            obj->const_base, rtems_rtl_delta_voids (obj->data_base, obj->const_base));
+    printf ("%-*cdata base     : %p (%zi)\n", print->indent, ' ',
+            obj->data_base, rtems_rtl_delta_voids (obj->bss_base, obj->data_base));
+    printf ("%-*cbss base      : %p (%zi)\n", print->indent, ' ',
+            obj->bss_base, obj->bss_size);
+  }
+  printf ("%-*cunresolved    : %lu\n", print->indent, ' ', obj->unresolved);
+  printf ("%-*csymbols       : %zi\n", print->indent, ' ', obj->global_syms);
+  printf ("%-*csymbol memory : %zi\n", print->indent, ' ', obj->global_size);
+  if (print->symbols)
+  {
+    int max_len = 0;
+    int s;
+    for (s = 0; s < obj->global_syms; ++s)
+    {
+      int len = strlen (obj->global_table[s].name);
+      if (len > max_len)
+        max_len = len;
+    }
+    for (s = 0; s < obj->global_syms; ++s)
+      printf ("%-*c%-*s = %p\n", print->indent + 2, ' ',
+              max_len, obj->global_table[s].name, obj->global_table[s].value);
+  }
+  printf ("\n");
+  return true;
+}
+
+/**
+ * Object unresolved symbols printer.
+ */
+static bool
+rtems_rtl_unresolved_printer (rtems_rtl_unresolv_rec_t* rec,
+                              void*                     data)
+{
+  rtems_rtl_obj_print_t* print = (rtems_rtl_obj_print_t*) data;
+  if (rec->type == rtems_rtl_unresolved_name)
+    printf ("%-*c%s\n", print->indent + 2, ' ', rec->rec.name.name);
+  return false;
+}
+
+/**
+ * Object print iterator.
+ */
+static bool
+rtems_rtl_obj_print_iterator (rtems_chain_node* node, void* data)
+{
+  rtems_rtl_obj_print_t* print = data;
+  rtems_rtl_obj_t*       obj = (rtems_rtl_obj_t*) node;
+  return rtems_rtl_obj_printer (print, obj);
+}
+
+static int
+rtems_rtl_shell_list (rtems_rtl_data_t* rtl, int argc, char *argv[])
+{
+  rtems_rtl_obj_print_t print;
+  print.rtl = rtl;
+  print.indent = 1;
+  print.oname = true;
+  print.names = true;
+  print.memory_map = true;
+  print.symbols = rtems_rtl_symbols_arg (argc, argv);
+  print.base = false;
+  rtems_rtl_chain_iterate (&rtl->objects,
+                           rtems_rtl_obj_print_iterator,
+                           &print);
+  return 0;
+}
+
+static int
+rtems_rtl_shell_sym (rtems_rtl_data_t* rtl, int argc, char *argv[])
+{
+  rtems_rtl_obj_print_t print;
+  print.rtl = rtl;
+  print.indent = 1;
+  print.oname = true;
+  print.names = false;
+  print.memory_map = false;
+  print.symbols = true;
+  print.base = rtems_rtl_base_arg (argc, argv);
+  rtems_rtl_chain_iterate (&rtl->objects,
+                           rtems_rtl_obj_print_iterator,
+                           &print);
+  printf ("Unresolved:\n");
+  rtems_rtl_unresolved_interate (rtems_rtl_unresolved_printer, &print);
+  return 0;
+}
+
+static int
+rtems_rtl_shell_object (rtems_rtl_data_t* rtl, int argc, char *argv[])
+{
+  return 0;
+}
+
+static void
+rtems_rtl_shell_usage (const char* arg)
+{
+  printf ("%s: Runtime Linker\n", arg);
+  printf ("  %s [-hl] <command>\n", arg);
+  printf ("   where:\n");
+  printf ("     command: A n RTL command. See -l for a list plus help.\n");
+  printf ("     -h:      This help\n");
+  printf ("     -l:      The command list.\n");
+}
+
+int
+rtems_rtl_shell_command (int argc, char* argv[])
+{
+  const rtems_rtl_shell_cmd_t table[] =
+  {
+    { "status", rtems_rtl_shell_status,
+      "Display the status of the RTL" },
+    { "list", rtems_rtl_shell_list,
+      "\tList the object files currently loaded" },
+    { "sym", rtems_rtl_shell_sym,
+      "\tDisplay the symbols, sym [<name>], sym -o <obj> [<name>]" },
+    { "obj", rtems_rtl_shell_object,
+      "\tDisplay the object details, obj <name>" }
+  };
+
+  int arg;
+  int t;
+
+  for (arg = 1; arg < argc; arg++)
+  {
+    if (argv[arg][0] != '-')
+      break;
+
+    switch (argv[arg][1])
+    {
+      case 'h':
+        rtems_rtl_shell_usage (argv[0]);
+        return 0;
+      case 'l':
+        printf ("%s: commands are:\n", argv[0]);
+        for (t = 0;
+             t < (sizeof (table) / sizeof (const rtems_rtl_shell_cmd_t));
+             ++t)
+          printf ("  %s\t%s\n", table[t].name, table[t].help);
+        return 0;
+      default:
+        printf ("error: unknown option: %s\n", argv[arg]);
+        return 1;
+    }
+  }
+
+  if ((argc - arg) < 1)
+    printf ("error: you need to provide a command, try %s -h\n", argv[0]);
+  else
+  {
+    for (t = 0;
+         t < (sizeof (table) / sizeof (const rtems_rtl_shell_cmd_t));
+         ++t)
+    {
+      if (strncmp (argv[arg], table[t].name, strlen (argv[arg])) == 0)
+      {
+        rtems_rtl_data_t* rtl = rtems_rtl_data ();
+        int               r;
+        if (!rtl)
+        {
+          printf ("error: cannot lock the linker\n");
+          return 1;
+        }
+        r = table[t].handler (rtl, argc - 1, argv + 1);
+        rtems_rtl_unlock ();
+        return r;
+      }
+    }
+    printf ("error: command not found: %s (try -h)\n", argv[arg]);
+  }
+
+  return 1;
+}
diff --git a/cpukit/libdl/rtl-shell.h b/cpukit/libdl/rtl-shell.h
new file mode 100644
index 0000000..ac9bb25
--- /dev/null
+++ b/cpukit/libdl/rtl-shell.h
@@ -0,0 +1,39 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker ELF Shell Support.
+ */
+
+#if !defined (_RTEMS_RTL_SHELL_H_)
+#define _RTEMS_RTL_SHELL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <stdint.h>
+
+/**
+ * The RTL single shell command contains sub-commands.
+ *
+ * @param argc The argument count.
+ * @param argv Array of argument strings.
+ * @retval 0 No error.
+ * @return int The exit code.
+ */
+int rtems_rtl_shell_command (int argc, char* argv[]);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/libdl/rtl-string.c b/cpukit/libdl/rtl-string.c
new file mode 100644
index 0000000..4a49b77
--- /dev/null
+++ b/cpukit/libdl/rtl-string.c
@@ -0,0 +1,32 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker String managment.
+ */
+
+#include <string.h>
+
+#include "rtl-allocator.h"
+#include "rtl-string.h"
+
+char*
+rtems_rtl_strdup (const char *s1)
+{
+  size_t len = strlen (s1);
+  char*  s2 = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT, len + 1, false);
+  if (s2)
+  {
+    memcpy (s2, s1, len);
+    s2[len] = '\0';
+  }
+  return s2;
+}
diff --git a/cpukit/libdl/rtl-string.h b/cpukit/libdl/rtl-string.h
new file mode 100644
index 0000000..a9ce6f5
--- /dev/null
+++ b/cpukit/libdl/rtl-string.h
@@ -0,0 +1,37 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker String managment.
+ */
+
+#if !defined (_RTEMS_RTL_STRING_H_)
+#define _RTEMS_RTL_STRING_H_
+
+#include "rtl-indirect-ptr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * A string duplicate that uses the RTL allocator.
+ *
+ * @param s1 The string to duplicate.
+ * @return char* The copy of the string. NULL if there is no memory.
+ */
+char* rtems_rtl_strdup (const char *s1);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/libdl/rtl-sym.c b/cpukit/libdl/rtl-sym.c
new file mode 100644
index 0000000..f806394
--- /dev/null
+++ b/cpukit/libdl/rtl-sym.c
@@ -0,0 +1,245 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object File Symbol Table.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-error.h"
+#include "rtl-sym.h"
+#include "rtl-trace.h"
+
+/**
+ * The single symbol forced into the global symbol table that is used to load a
+ * symbol table from an object file.
+ */
+static rtems_rtl_obj_sym_t global_sym_add =
+{
+  .name  = "rtems_rtl_base_sym_global_add",
+  .value = (void*) rtems_rtl_base_sym_global_add
+};
+
+static uint_fast32_t
+rtems_rtl_symbol_hash (const char *s)
+{
+  uint_fast32_t h = 5381;
+  unsigned char c;
+  for (c = *s; c != '\0'; c = *++s)
+    h = h * 33 + c;
+  return h & 0xffffffff;
+}
+
+static void
+rtems_rtl_symbol_global_insert (rtems_rtl_symbols_t* symbols,
+                                rtems_rtl_obj_sym_t* symbol)
+{
+  uint_fast32_t hash = rtems_rtl_symbol_hash (symbol->name);
+  rtems_chain_append (&symbols->buckets[hash % symbols->nbuckets],
+                      &symbol->node);
+}
+
+bool
+rtems_rtl_symbol_table_open (rtems_rtl_symbols_t* symbols,
+                             size_t               buckets)
+{
+  symbols->buckets = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_SYMBOL,
+                                          buckets * sizeof (rtems_chain_control),
+                                          true);
+  if (!symbols->buckets)
+  {
+    rtems_rtl_set_error (ENOMEM, "no memory for global symbol table");
+    return false;
+  }
+  symbols->nbuckets = buckets;
+  for (buckets = 0; buckets < symbols->nbuckets; ++buckets)
+    rtems_chain_initialize_empty (&symbols->buckets[buckets]);
+  rtems_rtl_symbol_global_insert (symbols, &global_sym_add);
+  return true;
+}
+
+void
+rtems_rtl_symbol_table_close (rtems_rtl_symbols_t* symbols)
+{
+  rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_SYMBOL, symbols->buckets);
+}
+
+bool
+rtems_rtl_symbol_global_add (rtems_rtl_obj_t*     obj,
+                             const unsigned char* esyms,
+                             unsigned int         size)
+{
+  rtems_rtl_symbols_t* symbols;
+  rtems_rtl_obj_sym_t* sym;
+  size_t               count;
+  size_t               s;
+  uint32_t             marker;
+
+  count = 0;
+  s = 0;
+  while ((s < size) && (esyms[s] != 0))
+  {
+    int l = strlen ((char*) &esyms[s]);
+    if ((esyms[s + l] != '\0') || ((s + l) > size))
+    {
+      rtems_rtl_set_error (EINVAL, "invalid exported symbol table");
+      return false;
+    }
+    ++count;
+    s += l + sizeof (unsigned long) + 1;
+  }
+
+  /*
+   * Check this is the correct end of the table.
+   */
+  marker = esyms[s + 1];
+  marker <<= 8;
+  marker |= esyms[s + 2];
+  marker <<= 8;
+  marker |= esyms[s + 3];
+  marker <<= 8;
+  marker |= esyms[s + 4];
+
+  if (marker != 0xdeadbeefUL)
+  {
+    rtems_rtl_set_error (ENOMEM, "invalid export symbol table");
+    return false;
+  }
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_GLOBAL_SYM))
+    printf ("rtl: global symbol add: %zi\n", count);
+
+  obj->global_size = count * sizeof (rtems_rtl_obj_sym_t);
+  obj->global_table = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_SYMBOL,
+                                           obj->global_size, true);
+  if (!obj->global_table)
+  {
+    obj->global_size = 0;
+    rtems_rtl_set_error (ENOMEM, "no memory for global symbols");
+    return false;
+  }
+
+  symbols = rtems_rtl_global_symbols ();
+
+  s = 0;
+  sym = obj->global_table;
+
+  while ((s < size) && (esyms[s] != 0))
+  {
+    /*
+     * Copy the void* using a union and memcpy to avoid any strict aliasing or
+     * alignment issues. The variable length of the label and the packed nature
+     * of the table means casting is not suitable.
+     */
+    union {
+      uint8_t data[sizeof (void*)];
+      void*   value;
+    } copy_voidp;
+    int b;
+
+    sym->name = (const char*) &esyms[s];
+    s += strlen (sym->name) + 1;
+    for (b = 0; b < sizeof (void*); ++b, ++s)
+      copy_voidp.data[b] = esyms[s];
+    sym->value = copy_voidp.value;
+    if (rtems_rtl_trace (RTEMS_RTL_TRACE_GLOBAL_SYM))
+      printf ("rtl: esyms: %s -> %8p\n", sym->name, sym->value);
+    if (rtems_rtl_symbol_global_find (sym->name) == NULL)
+      rtems_rtl_symbol_global_insert (symbols, sym);
+    ++sym;
+  }
+
+  obj->global_syms = count;
+
+  return true;
+}
+
+rtems_rtl_obj_sym_t*
+rtems_rtl_symbol_global_find (const char* name)
+{
+  rtems_rtl_symbols_t* symbols;
+  uint_fast32_t        hash;
+  rtems_chain_control* bucket;
+  rtems_chain_node*    node;
+
+  symbols = rtems_rtl_global_symbols ();
+
+  hash = rtems_rtl_symbol_hash (name);
+  bucket = &symbols->buckets[hash % symbols->nbuckets];
+  node = rtems_chain_first (bucket);
+
+  while (!rtems_chain_is_tail (bucket, node))
+  {
+    rtems_rtl_obj_sym_t* sym = (rtems_rtl_obj_sym_t*) node;
+    /*
+     * Use the hash. I could add this to the symbol but it uses more memory.
+     */
+    if (strcmp (name, sym->name) == 0)
+      return sym;
+    node = rtems_chain_next (node);
+  }
+
+  return NULL;
+}
+
+rtems_rtl_obj_sym_t*
+rtems_rtl_symbol_obj_find (rtems_rtl_obj_t* obj, const char* name)
+{
+  rtems_rtl_obj_sym_t* sym;
+  size_t               s;
+  /*
+   * Check the object file's symbols first. If not found search the
+   * global symbol table.
+   */
+  for (s = 0, sym = obj->global_table; s < obj->global_syms; ++s, ++sym)
+    if (strcmp (name, sym->name) == 0)
+      return sym;
+  return rtems_rtl_symbol_global_find (name);
+}
+
+void
+rtems_rtl_symbol_obj_add (rtems_rtl_obj_t* obj)
+{
+  rtems_rtl_symbols_t* symbols;
+  rtems_rtl_obj_sym_t* sym;
+  size_t               s;
+
+  symbols = rtems_rtl_global_symbols ();
+
+  for (s = 0, sym = obj->global_table; s < obj->global_syms; ++s, ++sym)
+    rtems_rtl_symbol_global_insert (symbols, sym);
+}
+
+void
+rtems_rtl_symbol_obj_erase (rtems_rtl_obj_t* obj)
+{
+  if (obj->global_table)
+  {
+    rtems_rtl_obj_sym_t* sym;
+    size_t               s;
+    for (s = 0, sym = obj->global_table; s < obj->global_syms; ++s, ++sym)
+        if (!rtems_chain_is_node_off_chain (&sym->node))
+          rtems_chain_extract (&sym->node);
+    rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_SYMBOL, obj->global_table);
+    obj->global_table = NULL;
+    obj->global_size = 0;
+    obj->global_syms = 0;
+  }
+}
diff --git a/cpukit/libdl/rtl-sym.h b/cpukit/libdl/rtl-sym.h
new file mode 100644
index 0000000..b793a54
--- /dev/null
+++ b/cpukit/libdl/rtl-sym.h
@@ -0,0 +1,128 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object File Symbol Table.
+ */
+
+#if !defined (_RTEMS_RTL_SYM_H_)
+#define _RTEMS_RTL_SYM_H_
+
+#include <rtems.h>
+#include "rtl-obj-fwd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * An object file symbol.
+ */
+typedef struct rtems_rtl_obj_sym_s
+{
+  rtems_chain_node node;    /**< The node's link in the chain. */
+  const char*      name;    /**< The symbol's name. */
+  void*            value;   /**< The value of the symbol. */
+  uint32_t         data;    /**< Format specific data. */
+} rtems_rtl_obj_sym_t;
+
+/**
+ * Table of symbols stored in a hash table.
+ */
+typedef struct rtems_rtl_symbols_s
+{
+  rtems_chain_control* buckets;
+  size_t               nbuckets;
+} rtems_rtl_symbols_t;
+
+/**
+ * Open a symbol table with the specified number of buckets.
+ *
+ * @param symbols The symbol table to open.
+ * @param buckets The number of buckets in the hash table.
+ * @retval true The symbol is open.
+ * @retval false The symbol table could not created. The RTL
+ *               error has the error.
+ */
+bool rtems_rtl_symbol_table_open (rtems_rtl_symbols_t* symbols,
+                                  size_t               buckets);
+
+/**
+ * Close the table and erase the hash table.
+ *
+ * @param symbols Close the symbol table.
+ */
+void rtems_rtl_symbol_table_close (rtems_rtl_symbols_t* symbols);
+
+/**
+ * Add a table of exported symbols to the symbol table.
+ *
+ * The export table is a series of symbol records and each record has two
+ * fields:
+ *
+ *  1. label
+ *  2. address
+ *
+ * The 'label' is an ASCIIZ string of variable length. The address is of size
+ * of an unsigned long for the target running the link editor. The byte order
+ * is defined by the machine type because the table should be built by the
+ * target compiler.
+ *
+ * The table is terminated with a nul string followed by the bytes 0xDE, 0xAD,
+ * 0xBE, and 0xEF. This avoids alignments issues.
+ *
+ * @param obj The object table the symbols are for.
+ * @param esyms The exported symbol table.
+ * @param size The size of the table in bytes.
+ */
+bool rtems_rtl_symbol_global_add (rtems_rtl_obj_t*     obj,
+                                  const unsigned char* esyms,
+                                  unsigned int         size);
+
+/**
+ * Find a symbol given the symbol label in the global symbol table.
+ *
+ * @param name The name as an ASCIIZ string.
+ * @retval NULL No symbol found.
+ * @return rtems_rtl_obj_sym_t* Reference to the symbol.
+ */
+rtems_rtl_obj_sym_t* rtems_rtl_symbol_global_find (const char* name);
+
+/**
+ * Find a symbol given the symbol label in the local object file.
+ *
+ * @param obj The object file to search.
+ * @param name The name as an ASCIIZ string.
+ * @retval NULL No symbol found.
+ * @return rtems_rtl_obj_sym_t* Reference to the symbol.
+ */
+rtems_rtl_obj_sym_t* rtems_rtl_symbol_obj_find (rtems_rtl_obj_t* obj,
+                                                const char*      name);
+
+/**
+ * Add the object file's symbols to the global table.
+ *
+ * @param obj The object file the symbols are to be added.
+ */
+void rtems_rtl_symbol_obj_add (rtems_rtl_obj_t* obj);
+
+/**
+ * Erase the object file's symbols.
+ *
+ * @param obj The object file the symbols are to be erased from.
+ */
+void rtems_rtl_symbol_obj_erase (rtems_rtl_obj_t* obj);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/libdl/rtl-trace.c b/cpukit/libdl/rtl-trace.c
new file mode 100644
index 0000000..d577f99
--- /dev/null
+++ b/cpukit/libdl/rtl-trace.c
@@ -0,0 +1,134 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtld
+ *
+ * @brief RTEMS Run-Time Link Editor Trace
+ *
+ * A configurable tracer for the RTL. See the header file for the enable and
+ * disable.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "rtl-trace.h"
+
+#if RTEMS_RTL_TRACE
+static rtems_rtl_trace_mask rtems_rtl_trace_flags;
+
+bool
+rtems_rtl_trace (rtems_rtl_trace_mask mask)
+{
+  bool result = false;
+  if (mask & rtems_rtl_trace_flags)
+    result = true;
+  return result;
+}
+
+rtems_rtl_trace_mask
+rtems_rtl_trace_set_mask (rtems_rtl_trace_mask mask)
+{
+  rtems_rtl_trace_mask state = rtems_rtl_trace_flags;
+  rtems_rtl_trace_flags |= mask;
+  return state;
+}
+
+rtems_rtl_trace_mask
+rtems_rtl_trace_clear_mask (rtems_rtl_trace_mask mask)
+{
+  rtems_rtl_trace_mask state = rtems_rtl_trace_flags;
+  rtems_rtl_trace_flags &= ~mask;
+  return state;
+}
+
+int
+rtems_rtl_trace_shell_command (int argc, char *argv[])
+{
+  const char* table[] =
+  {
+    "load",
+    "unload",
+    "section",
+    "symbol",
+    "reloc",
+    "global-sym",
+    "load-sect",
+    "allocator",
+    "unresolved",
+    "detail"
+  };
+
+  rtems_rtl_trace_mask set_value = 0;
+  rtems_rtl_trace_mask clear_value = 0;
+  bool                 set = true;
+  int                  arg;
+  int                  t;
+
+  for (arg = 1; arg < argc; arg++)
+  {
+    if (argv[arg][0] == '-')
+    {
+      switch (argv[arg][1])
+      {
+        case 'h':
+          printf ("usage: %s [-hl] [set/clear] [flags]\n", argv[0]);
+          return 0;
+        case 'l':
+          printf ("%s: valid flags to set or clear are:\n", argv[0]);
+          for (t = 0; t < (sizeof (table) / sizeof (const char*)); t++)
+            printf ("  %s\n", table[t]);
+          return 0;
+        default:
+          printf ("error: unknown option\n");
+          return 1;
+      }
+    }
+    else
+    {
+      if (strcmp (argv[arg], "set") == 0)
+        set = true;
+      if (strcmp (argv[arg], "clear") == 0)
+        set = false;
+      else if (strcmp (argv[arg], "all") == 0)
+      {
+        if (set)
+          set_value = RTEMS_RTL_TRACE_ALL;
+        else
+          clear_value = RTEMS_RTL_TRACE_ALL;
+      }
+      else
+      {
+        for (t = 0; t < (sizeof (table) / sizeof (const char*)); t++)
+        {
+          if (strcmp (argv[arg], table[t]) == 0)
+          {
+            if (set)
+              set_value = 1 << t;
+            else
+              clear_value = 1 << t;
+            break;
+          }
+        }
+      }
+
+      rtems_rtl_trace_flags |= set_value;
+      rtems_rtl_trace_flags &= ~clear_value;
+    }
+  }
+
+  return 0;
+}
+
+#endif
diff --git a/cpukit/libdl/rtl-trace.h b/cpukit/libdl/rtl-trace.h
new file mode 100644
index 0000000..1a5ee97
--- /dev/null
+++ b/cpukit/libdl/rtl-trace.h
@@ -0,0 +1,100 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker ELF Trace Support.
+ */
+
+#if !defined (_RTEMS_RTL_TRACE_H_)
+#define _RTEMS_RTL_TRACE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+/**
+ * Set to 1 to build trace support in to the RTL code.
+ */
+#define RTEMS_RTL_TRACE 1
+
+/**
+ * The type of the mask.
+ */
+typedef uint32_t rtems_rtl_trace_mask;
+
+/**
+ * List of tracing bits for the various parts of the link editor.
+ */
+#define RTEMS_RTL_TRACE_ALL                    (0xffffffffUL)
+#define RTEMS_RTL_TRACE_LOAD                   (1UL << 0)
+#define RTEMS_RTL_TRACE_UNLOAD                 (1UL << 1)
+#define RTEMS_RTL_TRACE_SECTION                (1UL << 2)
+#define RTEMS_RTL_TRACE_SYMBOL                 (1UL << 3)
+#define RTEMS_RTL_TRACE_RELOC                  (1UL << 4)
+#define RTEMS_RTL_TRACE_GLOBAL_SYM             (1UL << 5)
+#define RTEMS_RTL_TRACE_LOAD_SECT              (1UL << 6)
+#define RTEMS_RTL_TRACE_ALLOCATOR              (1UL << 7)
+#define RTEMS_RTL_TRACE_UNRESOLVED             (1UL << 8)
+#define RTEMS_RTL_TRACE_DETAIL                 (1UL << 9)
+
+/**
+ * Call to check if this part is bring traced. If RTEMS_RTL_TRACE is defined to
+ * 0 the code is dead code elminiated when built with -Os, -O2, or higher.
+ *
+ * @param mask The part of the API to trace.
+ * @retval true Tracing is active for the mask.
+ * @retval false Do not trace.
+ */
+#if RTEMS_RTL_TRACE
+bool rtems_rtl_trace (rtems_rtl_trace_mask mask);
+#else
+#define rtems_rtl_trace(_m) (0)
+#endif
+
+/**
+ * Set the mask.
+ *
+ * @param mask The mask bits to set.
+ * @return The previous mask.
+ */
+#if RTEMS_RTL_TRACE
+rtems_rtl_trace_mask rtems_rtl_trace_set_mask (rtems_rtl_trace_mask mask);
+#else
+#define rtems_rtl_trace_set_mask(_m)
+#endif
+
+/**
+ * Clear the mask.
+ *
+ * @param mask The mask bits to clear.
+ * @return The previous mask.
+ */
+#if RTEMS_RTL_TRACE
+rtems_rtl_trace_mask rtems_rtl_trace_clear_mask (rtems_rtl_trace_mask mask);
+#else
+#define rtems_rtl_trace_clear_mask(_m)
+#endif
+
+/**
+ * Add shell trace shell command.
+ */
+#if RTEMS_RTL_TRACE
+int rtems_rtl_trace_shell_command (int argc, char *argv[]);
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/libdl/rtl-unresolved.c b/cpukit/libdl/rtl-unresolved.c
new file mode 100644
index 0000000..0dbde0a
--- /dev/null
+++ b/cpukit/libdl/rtl-unresolved.c
@@ -0,0 +1,471 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object File Unresolved Relocations Table.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-error.h"
+#include "rtl-unresolved.h"
+#include "rtl-trace.h"
+
+static rtems_rtl_unresolv_block_t*
+rtems_rtl_unresolved_block_alloc (rtems_rtl_unresolved_t* unresolved)
+{
+  /*
+   * The block header contains a record.
+   */
+  size_t size =
+    (sizeof(rtems_rtl_unresolv_block_t) +
+     (sizeof(rtems_rtl_unresolv_rec_t) * (unresolved->block_recs - 1)));
+  rtems_rtl_unresolv_block_t* block =
+    rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_EXTERNAL, size, true);
+  if (block)
+    rtems_chain_append (&unresolved->blocks, &block->link);
+  else
+    rtems_rtl_set_error (ENOMEM, "no memory for unresolved block");
+  return block;
+}
+
+static size_t
+rtems_rtl_unresolved_name_recs (const char* name)
+{
+  size_t length = strlen (name);
+  return ((length + sizeof(rtems_rtl_unresolv_name_t) - 1) /
+          sizeof(rtems_rtl_unresolv_name_t));
+}
+
+static int
+rtems_rtl_unresolved_rec_index (rtems_rtl_unresolv_block_t* block,
+                                rtems_rtl_unresolv_rec_t* rec)
+{
+  return (rec - &block->rec) / sizeof (rtems_rtl_unresolv_rec_t);
+}
+
+static rtems_rtl_unresolv_rec_t*
+rtems_rtl_unresolved_rec_first (rtems_rtl_unresolv_block_t* block)
+{
+  return &block->rec;
+}
+
+static rtems_rtl_unresolv_rec_t*
+rtems_rtl_unresolved_rec_next (rtems_rtl_unresolv_rec_t* rec)
+{
+
+  switch (rec->type)
+  {
+    case rtems_rtl_unresolved_empty:
+      /*
+       * Empty returns NULL. The end of the records in the block.
+       */
+      rec = NULL;
+      break;
+
+    case rtems_rtl_unresolved_name:
+      /*
+       * Determine how many records the name occupies. Round up.
+       */
+      rec += ((rec->rec.name.length + sizeof(rtems_rtl_unresolv_name_t) - 1) /
+              sizeof(rtems_rtl_unresolv_name_t));
+      break;
+
+    case rtems_rtl_unresolved_reloc:
+      ++rec;
+      break;
+
+    default:
+      break;
+  }
+
+  return rec;
+}
+
+static bool
+rtems_rtl_unresolved_rec_is_last (rtems_rtl_unresolv_block_t* block,
+                                  rtems_rtl_unresolv_rec_t*   rec)
+{
+  int index = (rec - &block->rec) / sizeof (rec);
+  return !rec || (index >= block->recs) || (rec->type == rtems_rtl_unresolved_empty);
+}
+
+static rtems_rtl_unresolv_rec_t*
+rtems_rtl_unresolved_rec_first_free (rtems_rtl_unresolv_block_t* block)
+{
+  return &block->rec + block->recs;
+}
+
+static int
+rtems_rtl_unresolved_find_name (rtems_rtl_unresolved_t* unresolved,
+                                const char*             name,
+                                bool                    update_refcount)
+{
+  size_t length = strlen (name);
+  int    index = 1;
+
+  rtems_chain_node* node = rtems_chain_first (&unresolved->blocks);
+  while (!rtems_chain_is_tail (&unresolved->blocks, node))
+  {
+    rtems_rtl_unresolv_block_t* block = (rtems_rtl_unresolv_block_t*) node;
+    rtems_rtl_unresolv_rec_t* rec = rtems_rtl_unresolved_rec_first (block);
+
+    while (!rtems_rtl_unresolved_rec_is_last (block, rec))
+    {
+      if (rec->type == rtems_rtl_unresolved_name)
+      {
+        if ((rec->rec.name.length == length)
+            && (strcmp (rec->rec.name.name, name)))
+        {
+          if (update_refcount)
+            ++rec->rec.name.refs;
+          return index;
+        }
+        ++index;
+      }
+      rec = rtems_rtl_unresolved_rec_next (rec);
+    }
+
+    node = rtems_chain_next (node);
+  }
+
+  return 0 - index;
+}
+
+/**
+ * Struct to pass relocation data in the interator.
+ */
+typedef struct rtems_rtl_unresolved_reloc_data_s
+{
+  uint16_t                  name;     /**< Name index. */
+  rtems_rtl_unresolv_rec_t* name_rec; /**< Name record. */
+  rtems_rtl_obj_sym_t*      sym;      /**< The symbol record. */
+} rtems_rtl_unresolved_reloc_data_t;
+
+static bool
+rtems_rtl_unresolved_resolve_reloc (rtems_rtl_unresolv_rec_t* rec,
+                                    void*                     data)
+{
+  if (rec->type == rtems_rtl_unresolved_reloc)
+  {
+    rtems_rtl_unresolved_reloc_data_t* rd;
+    rd = (rtems_rtl_unresolved_reloc_data_t*) data;
+
+    if (rec->rec.reloc.name == rd->name)
+    {
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
+        printf ("rtl: unresolv: resolve reloc: %s\n", rd->name_rec->rec.name.name);
+
+      rtems_rtl_obj_relocate_unresolved (&rec->rec.reloc, rd->sym);
+
+      /*
+       * Set the object pointer to NULL to indicate the record is not used
+       * anymore. Update the reference count of the name. The sweep after
+       * relocating will remove the reloc records with obj set to NULL and
+       * names with a reference count of 0.
+       */
+      rec->rec.reloc.obj = NULL;
+      if (rd->name_rec && rd->name_rec->rec.name.refs)
+        --rd->name_rec->rec.name.refs;
+    }
+  }
+  return false;
+}
+
+static bool
+rtems_rtl_unresolved_resolve_iterator (rtems_rtl_unresolv_rec_t* rec,
+                                       void*                     data)
+{
+  if (rec->type == rtems_rtl_unresolved_name)
+  {
+    rtems_rtl_unresolved_reloc_data_t* rd;
+    rd = (rtems_rtl_unresolved_reloc_data_t*) data;
+
+    ++rd->name;
+
+    if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
+      printf ("rtl: unresolv: lookup: %d: %s\n", rd->name, rec->rec.name.name);
+
+    rd->sym = rtems_rtl_symbol_global_find (rec->rec.name.name);
+
+    if (rd->sym)
+    {
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
+        printf ("rtl: unresolv: found: %s\n", rec->rec.name.name);
+
+      rd->name_rec = rec;
+
+      rtems_rtl_unresolved_interate (rtems_rtl_unresolved_resolve_reloc, rd);
+
+      rd->name_rec = NULL;
+      rd->sym = NULL;
+    }
+  }
+
+  return false;
+}
+
+static void
+rtems_rtl_unresolved_clean_block (rtems_rtl_unresolv_block_t* block,
+                                  rtems_rtl_unresolv_rec_t* rec,
+                                  size_t count,
+                                  size_t recs_per_block)
+{
+  size_t index = rtems_rtl_unresolved_rec_index (block, rec);
+  size_t bytes =
+    (block->recs - index - count) * sizeof (rtems_rtl_unresolv_rec_t);
+  if (bytes)
+    memmove (rec, rec + count, bytes);
+  --block->recs;
+  bytes = count * sizeof (rtems_rtl_unresolv_rec_t);
+  memset (&block->rec + block->recs, 0, bytes);
+}
+
+static void
+rtems_rtl_unresolved_compact (void)
+{
+  rtems_rtl_unresolved_t* unresolved = rtems_rtl_unresolved ();
+  if (unresolved)
+  {
+    /*
+     * Iterate backwards over the blocks removing any used records. A block is
+     * compacted moving up the block.
+     */
+    rtems_chain_node* node = rtems_chain_last (&unresolved->blocks);
+    while (!rtems_chain_is_head (&unresolved->blocks, node))
+    {
+      rtems_chain_node* prev = rtems_chain_previous (node);
+      rtems_rtl_unresolv_block_t* block = (rtems_rtl_unresolv_block_t*) node;
+      rtems_rtl_unresolv_rec_t* rec = rtems_rtl_unresolved_rec_first (block);
+
+      while (!rtems_rtl_unresolved_rec_is_last (block, rec))
+      {
+        bool next = true;
+
+        if (rec->type == rtems_rtl_unresolved_name)
+        {
+          if (rec->rec.name.refs == 0)
+          {
+            size_t name_recs = rtems_rtl_unresolved_name_recs (rec->rec.name.name);
+            rtems_rtl_unresolved_clean_block (block, rec, name_recs,
+                                              unresolved->block_recs);
+            next = false;
+          }
+        }
+        else if (rec->type == rtems_rtl_unresolved_reloc)
+        {
+          if (!rec->rec.reloc.obj)
+          {
+            rtems_rtl_unresolved_clean_block (block, rec, 1,
+                                              unresolved->block_recs);
+            next = false;
+          }
+        }
+
+        if (next)
+          rec = rtems_rtl_unresolved_rec_next (rec);
+      }
+
+      if (block->recs == 0)
+      {
+        rtems_chain_extract (node);
+        free (block);
+      }
+
+      node = prev;
+    }
+  }
+}
+
+bool
+rtems_rtl_unresolved_table_open (rtems_rtl_unresolved_t* unresolved,
+                                 size_t                  block_recs)
+{
+  unresolved->marker = 0xdeadf00d;
+  unresolved->block_recs = block_recs;
+  rtems_chain_initialize_empty (&unresolved->blocks);
+  return true;
+}
+
+void
+rtems_rtl_unresolved_table_close (rtems_rtl_unresolved_t* unresolved)
+{
+  rtems_chain_node* node = rtems_chain_first (&unresolved->blocks);
+  while (!rtems_chain_is_tail (&unresolved->blocks, node))
+  {
+    rtems_chain_node* next = rtems_chain_next (node);
+    free (node);
+    node = next;
+  }
+}
+
+bool
+rtems_rtl_unresolved_interate (rtems_rtl_unresolved_iterator_t iterator,
+                               void*                           data)
+{
+  rtems_rtl_unresolved_t* unresolved = rtems_rtl_unresolved ();
+  if (unresolved)
+  {
+    rtems_chain_node* node = rtems_chain_first (&unresolved->blocks);
+    while (!rtems_chain_is_tail (&unresolved->blocks, node))
+    {
+      rtems_rtl_unresolv_block_t* block = (rtems_rtl_unresolv_block_t*) node;
+      rtems_rtl_unresolv_rec_t* rec = rtems_rtl_unresolved_rec_first (block);
+
+      while (!rtems_rtl_unresolved_rec_is_last (block, rec))
+      {
+        if (iterator (rec, data))
+          return true;
+        rec = rtems_rtl_unresolved_rec_next (rec);
+      }
+
+      node = rtems_chain_next (node);
+    }
+  }
+  return false;
+}
+
+bool
+rtems_rtl_unresolved_add (rtems_rtl_obj_t*        obj,
+                          const uint16_t          flags,
+                          const char*             name,
+                          const uint16_t          sect,
+                          const rtems_rtl_word_t* rel)
+{
+  rtems_rtl_unresolved_t* unresolved;
+  rtems_chain_node* node;
+  rtems_rtl_unresolv_block_t* block;
+  rtems_rtl_unresolv_rec_t* rec;
+  int name_index;
+  size_t name_recs;
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
+    printf ("rtl: unresolv: add: %s(s:%d) -> %s\n",
+            rtems_rtl_obj_oname (obj), sect, name);
+
+  unresolved = rtems_rtl_unresolved ();
+  if (!unresolved)
+    return false;
+
+  /*
+   * Find the first block with a spare record.
+   */
+  node = rtems_chain_first (&unresolved->blocks);
+  block = NULL;
+  while (!rtems_chain_is_tail (&unresolved->blocks, node))
+  {
+    block = (rtems_rtl_unresolv_block_t*) node;
+    if (block->recs < unresolved->block_recs)
+      break;
+    block = NULL;
+    node = rtems_chain_next (node);
+  }
+
+  /*
+   * No blocks with any spare records, allocate a new block.
+   */
+  if (!block)
+  {
+    block = rtems_rtl_unresolved_block_alloc (unresolved);
+    if (!block)
+      return false;
+  }
+
+  name_index = rtems_rtl_unresolved_find_name (unresolved, name, true);
+  name_recs = rtems_rtl_unresolved_name_recs (name);
+
+  /*
+   * An index less than 0 means the name is present and "0 - index" is the next
+   * index to use.
+   */
+  if (name_index < 0)
+  {
+    rtems_rtl_unresolv_block_t* name_block = block;
+
+    /*
+     * Is there enough room to fit the name ? It not add a new block.
+     */
+    if (name_recs > (unresolved->block_recs - block->recs))
+    {
+      name_block = rtems_rtl_unresolved_block_alloc (unresolved);
+      if (!name_block)
+        return false;
+    }
+
+    rec = rtems_rtl_unresolved_rec_first_free (name_block);
+    rec->type = rtems_rtl_unresolved_name;
+    rec->rec.name.refs = 1;
+    rec->rec.name.length = strlen (name) + 1;
+    memcpy ((void*) &rec->rec.name.name[0], name, rec->rec.name.length + 1);
+    block->recs += name_recs;
+    name_index = 0 - name_index;
+
+    /*
+     * If the name block is the reloc block and it is full allocate a new
+     * block for the relocation record.
+     */
+    if ((block == name_block) && (block->recs >= unresolved->block_recs))
+    {
+      block = rtems_rtl_unresolved_block_alloc (unresolved);
+      if (!block)
+        return false;
+    }
+  }
+
+  rec = rtems_rtl_unresolved_rec_first_free (block);
+  rec->type = rtems_rtl_unresolved_reloc;
+  rec->rec.reloc.obj = obj;
+  rec->rec.reloc.flags = flags;
+  rec->rec.reloc.name = name_index;
+  rec->rec.reloc.sect = sect;
+  rec->rec.reloc.rel[0] = rel[0];
+  rec->rec.reloc.rel[1] = rel[1];
+  rec->rec.reloc.rel[2] = rel[2];
+
+  ++block->recs;
+
+  return true;
+}
+
+void
+rtems_rtl_unresolved_resolve (void)
+{
+  rtems_rtl_unresolved_reloc_data_t rd;
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
+    printf ("rtl: unresolv: global resolve\n");
+  rd.name = 0;
+  rd.name_rec = NULL;
+  rd.sym = NULL;
+  rtems_rtl_unresolved_interate (rtems_rtl_unresolved_resolve_iterator, &rd);
+  rtems_rtl_unresolved_compact ();
+}
+
+bool
+rtems_rtl_unresolved_remove (rtems_rtl_obj_t*        obj,
+                             const char*             name,
+                             const uint16_t          sect,
+                             const rtems_rtl_word_t* rel)
+{
+  rtems_rtl_unresolved_t* unresolved;
+  unresolved = rtems_rtl_unresolved ();
+  if (!unresolved)
+    return false;
+  return false;
+}
+
diff --git a/cpukit/libdl/rtl-unresolved.h b/cpukit/libdl/rtl-unresolved.h
new file mode 100644
index 0000000..5cc5162
--- /dev/null
+++ b/cpukit/libdl/rtl-unresolved.h
@@ -0,0 +1,212 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object File Unresolved Relocations Table.
+ *
+ * The unresolved relocation table holds relocations in a loaded object file
+ * which reference unresolved external symbols. The support is needed to allow
+ * dependent object files to load. In the case of dependent object files one
+ * will have unresolved externals until the dependent object file is also
+ * loaded. There is no load order that resolves this.
+ *
+ * The unresolved relocation table is a single table used by all object files
+ * with unresolved symbols. It made of blocks linked together where blocks are
+ * allocated as requiered. The table is always maintained compacted. That is as
+ * relocations are resolved and removed the table is compacted. The only
+ * pointer in the table is the object file poniter. This is used to identify
+ * which object the relocation belongs to. There are no linking or back
+ * pointers in the unresolved relocations table. The table is scanned for each
+ * object file's relocations. This is not fast but the table should be small
+ * and if it happens to grow large you have other more pressing issues to
+ * resolve in your application.
+ *
+ * The table holds two (2) types of records:
+ *
+ *  # Symbol name strings.
+ *  # Relocations.
+ *
+ * The symbol name a relocation references is held in a specific symbol name
+ * string record in the table the relocation record references. The record
+ * counts the number of references and the string is removed from the table
+ * when the reference count reaches 0. There can be many relocations
+ * referencing the symbol. The strings are referenced by a single 16bit
+ * unsigned integer which is the count of the string in the table.
+ *
+ * The section the relocation is for in the object is the section number. The
+ * relocation data is series of machine word sized fields:
+ *
+ * # Offset in the section.
+ * # Relocation info (format specific)
+ * # Additional format specific data.
+ */
+
+#if !defined (_RTEMS_RTL_UNRESOLVED_H_)
+#define _RTEMS_RTL_UNRESOLVED_H_
+
+#include <rtems.h>
+#include "rtl-obj-fwd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Hack to work around machine size. This needs to be cleaned up
+ * to better support 64bit targets.
+ */
+typedef uint32_t rtems_rtl_word_t;
+
+/**
+ * The types of records in the blocks.
+ */
+typedef enum rtems_rtl_unresolved_rtype_e
+{
+  rtems_rtl_unresolved_empty = 0,  /**< The records is empty. Must always be 0 */
+  rtems_rtl_unresolved_name = 1,   /**< The record is a name. */
+  rtems_rtl_unresolved_reloc = 2   /**< The record is a relocation record. */
+} rtems_rtl_unresolved_rtype_t;
+
+/**
+ * Unresolved externals symbol names. The names are reference counted and
+ * separate from the relocation records because a number of records could
+ * reference the same symbol name.
+ */
+typedef struct rtems_rtl_unresolv_name_s
+{
+  uint16_t refs;       /**< The number of references to this name. */
+  uint16_t length;     /**< The length of this name. */
+  const char name[12]; /**< The symbol name. */
+} rtems_rtl_unresolv_name_t;
+
+/**
+ * Unresolved externals symbols require the relocation records to be held
+ * and references.
+ */
+typedef struct rtems_rtl_unresolv_reloc_s
+{
+  rtems_rtl_obj_t* obj;     /**< The relocation's object file. */
+  uint16_t         flags;   /**< Format specific flags. */
+  uint16_t         name;    /**< The symbol's name. */
+  uint16_t         sect;    /**< The target section. */
+  rtems_rtl_word_t rel[3];  /**< Relocation record. */
+} rtems_rtl_unresolv_reloc_t;
+
+/**
+ * Unresolved externals records.
+ */
+typedef struct rtems_rtl_unresolv_rec_s
+{
+  rtems_rtl_unresolved_rtype_t type;
+  union
+  {
+    rtems_rtl_unresolv_name_t name;    /**< The name, or */
+    rtems_rtl_unresolv_reloc_t reloc;  /**< the relocation record. */
+  } rec;
+} rtems_rtl_unresolv_rec_t;
+
+/**
+ * Unresolved blocks.
+ */
+typedef struct rtems_rtl_unresolv_block_s
+{
+  rtems_chain_node         link; /**< Blocks are chained. */
+  uint32_t                 recs; /**< The number of records in the block. */
+  rtems_rtl_unresolv_rec_t rec;  /**< The records. More follow. */
+} rtems_rtl_unresolv_block_t;
+
+/**
+ * Unresolved table holds the names and relocations.
+ */
+typedef struct rtems_rtl_unresolved_s
+{
+  uint32_t marker;
+  size_t              block_recs; /**< The records per blocks allocated. */
+  rtems_chain_control blocks;     /**< List of blocks. */
+} rtems_rtl_unresolved_t;
+
+/**
+ * The iterator function used to iterate over the unresolved table.
+ *
+ * @param rec The current iterator.
+ * @param data The user data.
+ * @retval true The iterator has finished.
+ * @retval false The iterator has not finished. Keep iterating.
+ */
+typedef bool rtems_rtl_unresolved_iterator_t (rtems_rtl_unresolv_rec_t* rec,
+                                              void*                     data);
+
+/**
+ * Open an unresolved relocation table.
+ *
+ * @param unresolv The unresolved table to open.
+ * @param block_records The number of records per block allocated.
+ * @retval true The table is open.
+ * @retval false The unresolved relocation table could not created. The RTL
+ *               error has the error.
+ */
+bool rtems_rtl_unresolved_table_open (rtems_rtl_unresolved_t* unresolved,
+                                      size_t                  block_records);
+
+/**
+ * Close the table and erase the blocks.
+ *
+ * @param unreolved Close the unresolved table.
+ */
+void rtems_rtl_unresolved_table_close (rtems_rtl_unresolved_t* unresolved);
+
+/**
+ * Iterate over the table of unresolved entries.
+ */
+bool rtems_rtl_unresolved_interate (rtems_rtl_unresolved_iterator_t iterator,
+                                    void*                           data);
+
+/**
+ * Add a relocation to the list of unresolved relocations.
+ *
+ * @param unresolved The unresolved symbol table.
+ * @param obj The object table the symbols are for.
+ * @param flags Format specific flags.
+ * @param name The symbol name the relocation references.
+ * @param sect The target section number the relocation references.
+ * @param rel The format specific relocation data.
+ * @retval true The relocation has been added.
+ * @retval false The relocation could not be added.
+ */
+bool rtems_rtl_unresolved_add (rtems_rtl_obj_t*        obj,
+                               const uint16_t          flags,
+                               const char*             name,
+                               const uint16_t          sect,
+                               const rtems_rtl_word_t* rel);
+
+/**
+ * Resolve the unresolved symbols.
+ */
+void rtems_rtl_unresolved_resolve (void);
+
+/**
+ * Remove a relocation from the list of unresolved relocations.
+ *
+ * @param unresolved The unresolved symbol table.
+ * @param obj The object table the symbols are for.
+ * @param esyms The exported symbol table.
+ * @param size The size of the table in bytes.
+ */
+bool rtems_rtl_unresolved_remove (rtems_rtl_obj_t*        obj,
+                                  const char*             name,
+                                  const uint16_t          sect,
+                                  const rtems_rtl_word_t* rel);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/libdl/rtl.c b/cpukit/libdl/rtl.c
new file mode 100644
index 0000000..c55cd94
--- /dev/null
+++ b/cpukit/libdl/rtl.c
@@ -0,0 +1,637 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtld
+ *
+ * @brief RTEMS Run-Time Link Editor
+ *
+ * This is the RTL implementation.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <rtems/libio_.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-allocator.h"
+#include "rtl-error.h"
+#include "rtl-string.h"
+#include "rtl-trace.h"
+
+/**
+ * Semaphore configuration to create a mutex.
+ */
+#define RTEMS_MUTEX_ATTRIBS \
+  (RTEMS_PRIORITY | RTEMS_BINARY_SEMAPHORE | \
+   RTEMS_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL)
+
+/**
+ * Symbol table cache size. They can be big so the cache needs space to work.
+ */
+#define RTEMS_RTL_ELF_SYMBOL_CACHE (2048)
+
+/**
+ * String table cache size.
+ */
+#define RTEMS_RTL_ELF_STRING_CACHE (2048)
+
+/**
+ * Relocations table cache size.
+ */
+#define RTEMS_RTL_ELF_RELOC_CACHE (2048)
+
+/**
+ * Decompression output buffer.
+ */
+#define RTEMS_RTL_COMP_OUTPUT (2048)
+
+/**
+ * Static RTL data is returned to the user when the linker is locked.
+ */
+static rtems_rtl_data_t* rtl;
+
+/**
+ * Define a default base global symbol loader function that is weak
+ * so a real table can be linked in when the user wants one.
+ */
+void rtems_rtl_base_global_syms_init (void) __attribute__ ((weak));
+void
+rtems_rtl_base_global_syms_init (void)
+{
+  /*
+   * Do nothing.
+   */
+}
+
+static bool
+rtems_rtl_data_init (void)
+{
+  /*
+   * Lock the RTL. We only create a lock if a call is made. First we test if a
+   * lock is present. If one is present we lock it. If not the libio lock is
+   * locked and we then test the lock again. If not present we create the lock
+   * then release libio lock.
+   */
+  if (!rtl)
+  {
+    rtems_libio_lock ();
+
+    if (!rtl)
+    {
+      rtems_status_code sc;
+      rtems_id          lock;
+
+      /*
+       * Always in the heap.
+       */
+      rtl = malloc (sizeof (rtems_rtl_data_t));
+      if (!rtl)
+      {
+        errno = ENOMEM;
+        return false;
+      }
+
+      *rtl = (rtems_rtl_data_t) { 0 };
+
+      /*
+       * The initialise the allocator data.
+       */
+      rtems_rtl_alloc_initialise (&rtl->allocator);
+
+      /*
+       * Create the RTL lock.
+       */
+      sc = rtems_semaphore_create (rtems_build_name ('R', 'T', 'L', 'D'),
+                                   1, RTEMS_MUTEX_ATTRIBS,
+                                   RTEMS_NO_PRIORITY, &lock);
+      if (sc != RTEMS_SUCCESSFUL)
+      {
+        free (rtl);
+        return false;
+      }
+
+      sc = rtems_semaphore_obtain (lock, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+      if (sc != RTEMS_SUCCESSFUL)
+      {
+        rtems_semaphore_delete (lock);
+        free (rtl);
+        return false;
+      }
+
+      rtl->lock = lock;
+
+      /*
+       * Initialise the objects list and create any required services.
+       */
+      rtems_chain_initialize_empty (&rtl->objects);
+
+      if (!rtems_rtl_symbol_table_open (&rtl->globals,
+                                        RTEMS_RTL_SYMS_GLOBAL_BUCKETS))
+      {
+        rtems_semaphore_delete (lock);
+        free (rtl);
+        return false;
+      }
+
+      if (!rtems_rtl_unresolved_table_open (&rtl->unresolved,
+                                            RTEMS_RTL_UNRESOLVED_BLOCK_SIZE))
+      {
+        rtems_rtl_symbol_table_close (&rtl->globals);
+        rtems_semaphore_delete (lock);
+        free (rtl);
+        return false;
+      }
+
+      if (!rtems_rtl_obj_cache_open (&rtl->symbols,
+                                     RTEMS_RTL_ELF_SYMBOL_CACHE))
+      {
+        rtems_rtl_symbol_table_close (&rtl->globals);
+        rtems_rtl_unresolved_table_close (&rtl->unresolved);
+        rtems_semaphore_delete (lock);
+        free (rtl);
+        return false;
+      }
+
+      if (!rtems_rtl_obj_cache_open (&rtl->strings,
+                                     RTEMS_RTL_ELF_STRING_CACHE))
+      {
+        rtems_rtl_obj_cache_close (&rtl->symbols);
+        rtems_rtl_unresolved_table_close (&rtl->unresolved);
+        rtems_rtl_symbol_table_close (&rtl->globals);
+        rtems_semaphore_delete (lock);
+        free (rtl);
+        return false;
+      }
+
+      if (!rtems_rtl_obj_cache_open (&rtl->relocs,
+                                     RTEMS_RTL_ELF_RELOC_CACHE))
+      {
+        rtems_rtl_obj_cache_close (&rtl->strings);
+        rtems_rtl_obj_cache_close (&rtl->symbols);
+        rtems_rtl_unresolved_table_close (&rtl->unresolved);
+        rtems_rtl_symbol_table_close (&rtl->globals);
+        rtems_semaphore_delete (lock);
+        free (rtl);
+        return false;
+      }
+
+      if (!rtems_rtl_obj_comp_open (&rtl->decomp,
+                                    RTEMS_RTL_COMP_OUTPUT))
+      {
+        rtems_rtl_obj_cache_close (&rtl->relocs);
+        rtems_rtl_obj_cache_close (&rtl->strings);
+        rtems_rtl_obj_cache_close (&rtl->symbols);
+        rtems_rtl_unresolved_table_close (&rtl->unresolved);
+        rtems_rtl_symbol_table_close (&rtl->globals);
+        rtems_semaphore_delete (lock);
+        free (rtl);
+        return false;
+      }
+
+      rtl->base = rtems_rtl_obj_alloc ();
+      if (!rtl->base)
+      {
+        rtems_rtl_obj_comp_close (&rtl->decomp);
+        rtems_rtl_obj_cache_close (&rtl->relocs);
+        rtems_rtl_obj_cache_close (&rtl->strings);
+        rtems_rtl_obj_cache_close (&rtl->symbols);
+        rtems_rtl_unresolved_table_close (&rtl->unresolved);
+        rtems_rtl_symbol_table_close (&rtl->globals);
+        rtems_semaphore_delete (lock);
+        free (rtl);
+        return false;
+      }
+
+      /*
+       * Need to malloc the memory so the free does not complain.
+       */
+      rtl->base->oname = rtems_rtl_strdup ("rtems-kernel");
+
+      rtems_chain_append (&rtl->objects, &rtl->base->link);
+    }
+
+    rtems_libio_unlock ();
+
+    rtems_rtl_path_append (".");
+
+    rtems_rtl_base_global_syms_init ();
+
+    rtems_rtl_unlock ();
+  }
+  return true;
+}
+
+rtems_rtl_data_t*
+rtems_rtl_data (void)
+{
+  return rtl;
+}
+
+rtems_rtl_symbols_t*
+rtems_rtl_global_symbols (void)
+{
+  if (!rtl)
+  {
+    rtems_rtl_set_error (ENOENT, "no rtl");
+    return NULL;
+  }
+  return &rtl->globals;
+}
+
+rtems_rtl_unresolved_t*
+rtems_rtl_unresolved (void)
+{
+  if (!rtl)
+  {
+    rtems_rtl_set_error (ENOENT, "no rtl");
+    return NULL;
+  }
+  return &rtl->unresolved;
+}
+
+void
+rtems_rtl_obj_caches (rtems_rtl_obj_cache_t** symbols,
+                      rtems_rtl_obj_cache_t** strings,
+                      rtems_rtl_obj_cache_t** relocs)
+{
+  if (!rtl)
+  {
+    if (symbols)
+       *symbols = NULL;
+    if (strings)
+      *strings = NULL;
+    if (relocs)
+      *relocs = NULL;
+  }
+  else
+  {
+    if (symbols)
+      *symbols = &rtl->symbols;
+    if (strings)
+      *strings = &rtl->strings;
+    if (relocs)
+      *relocs = &rtl->relocs;
+  }
+}
+
+void
+rtems_rtl_obj_caches_flush ()
+{
+  if (rtl)
+  {
+    rtems_rtl_obj_cache_flush (&rtl->symbols);
+    rtems_rtl_obj_cache_flush (&rtl->strings);
+    rtems_rtl_obj_cache_flush (&rtl->relocs);
+  }
+}
+
+void
+rtems_rtl_obj_comp (rtems_rtl_obj_comp_t** decomp,
+                    rtems_rtl_obj_cache_t* cache,
+                    int                    fd,
+                    int                    compression,
+                    off_t                  offset)
+{
+  if (!rtl)
+  {
+    *decomp = NULL;
+  }
+  else
+  {
+    *decomp = &rtl->decomp;
+    rtems_rtl_obj_comp_set (*decomp, cache, fd, compression, offset);
+  }
+}
+
+rtems_rtl_data_t*
+rtems_rtl_lock (void)
+{
+  rtems_status_code sc;
+
+  if (!rtems_rtl_data_init ())
+    return NULL;
+
+  sc = rtems_semaphore_obtain (rtl->lock,
+                               RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+  if (sc != RTEMS_SUCCESSFUL)
+  {
+    errno = EINVAL;
+    return NULL;
+  }
+
+  return rtl;
+}
+
+bool
+rtems_rtl_unlock (void)
+{
+  /*
+   * Not sure any error should be returned or an assert.
+   */
+  rtems_status_code sc;
+  sc = rtems_semaphore_release (rtl->lock);
+  if ((sc != RTEMS_SUCCESSFUL) && (errno == 0))
+  {
+    errno = EINVAL;
+    return false;
+  }
+  return true;
+}
+
+rtems_rtl_obj_t*
+rtems_rtl_check_handle (void* handle)
+{
+  rtems_rtl_obj_t*    obj;
+  rtems_chain_node* node;
+
+  obj = handle;
+  node = rtems_chain_first (&rtl->objects);
+
+  while (!rtems_chain_is_tail (&rtl->objects, node))
+  {
+    rtems_rtl_obj_t* check = (rtems_rtl_obj_t*) node;
+    if (check == obj)
+      return obj;
+    node = rtems_chain_next (node);
+  }
+
+  return NULL;
+}
+
+rtems_rtl_obj_t*
+rtems_rtl_find_obj (const char* name)
+{
+  rtems_chain_node* node;
+  rtems_rtl_obj_t*  found = NULL;
+  const char*       aname = NULL;
+  const char*       oname = NULL;
+  off_t             ooffset;
+
+  if (!rtems_rtl_parse_name (name, &aname, &oname, &ooffset))
+    return NULL;
+
+  node = rtems_chain_first (&rtl->objects);
+
+  while (!rtems_chain_is_tail (&rtl->objects, node))
+  {
+    rtems_rtl_obj_t* obj = (rtems_rtl_obj_t*) node;
+    if ((aname == NULL && strcmp (obj->oname, oname) == 0) ||
+        (aname != NULL &&
+         strcmp (obj->aname, aname) == 0 && strcmp (obj->oname, oname) == 0))
+    {
+        found = obj;
+        break;
+    }
+    node = rtems_chain_next (node);
+  }
+
+  if (!aname)
+    rtems_rtl_alloc_del(RTEMS_RTL_ALLOC_OBJECT, (void*) aname);
+
+  if (!oname)
+    rtems_rtl_alloc_del(RTEMS_RTL_ALLOC_OBJECT, (void*) oname);
+
+  return found;
+}
+
+rtems_rtl_obj_t*
+rtems_rtl_load_object (const char* name, int mode)
+{
+  rtems_rtl_obj_t* obj;
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
+    printf ("rtl: loading '%s'\n", name);
+
+  /*
+   * See if the object module has already been loaded.
+   */
+  obj = rtems_rtl_find_obj (name);
+  if (!obj)
+  {
+    /*
+     * Allocate a new object file descriptor and attempt to load it.
+     */
+    obj = rtems_rtl_obj_alloc ();
+    if (obj == NULL)
+    {
+      rtems_rtl_set_error (ENOMEM, "no memory for object descriptor");
+      return NULL;
+    }
+
+    /*
+     * Find the file in the file system using the search path. The fname field
+     * will point to a valid file name if found.
+     */
+    if (!rtems_rtl_obj_find_file (obj, name))
+    {
+      rtems_rtl_obj_free (obj);
+      return NULL;
+    }
+
+    rtems_chain_append (&rtl->objects, &obj->link);
+
+    if (!rtems_rtl_obj_load (obj))
+    {
+      rtems_rtl_obj_free (obj);
+      return NULL;
+    }
+
+    rtems_rtl_unresolved_resolve ();
+  }
+
+  /*
+   * Increase the number of users.
+   */
+  ++obj->users;
+
+  /*
+   * FIXME: Resolving existing unresolved symbols could add more constructors
+   *        lists that need to be called. Make a list in the obj load layer and
+   *        invoke the list here.
+   */
+
+  /*
+   * Run any local constructors if this is the first user because the object
+   * file will have just been loaded. Unlock the linker to avoid any dead locks
+   * if the object file needs to load files or update the symbol table. We also
+   * do not want a constructor to unload this object file.
+   */
+  if (obj->users == 1)
+  {
+    obj->flags |= RTEMS_RTL_OBJ_LOCKED;
+    rtems_rtl_unlock ();
+    rtems_rtl_obj_run_ctors (obj);
+    rtems_rtl_lock ();
+    obj->flags &= ~RTEMS_RTL_OBJ_LOCKED;
+  }
+
+  return obj;
+}
+
+bool
+rtems_rtl_unload_object (rtems_rtl_obj_t* obj)
+{
+  bool ok = true;
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNLOAD))
+    printf ("rtl: unloading '%s'\n", rtems_rtl_obj_fname (obj));
+
+  /*
+   * If the object is locked it cannot be unloaded and the unload fails.
+   */
+  if ((obj->flags & RTEMS_RTL_OBJ_LOCKED) == RTEMS_RTL_OBJ_LOCKED)
+  {
+    rtems_rtl_set_error (EINVAL, "cannot unload when locked");
+    return false;
+  }
+
+  /*
+   * Check the number of users in a safe manner. If this is the last user unload the
+   * object file from memory.
+   */
+  if (obj->users > 0)
+    --obj->users;
+
+  if (obj->users == 0)
+  {
+    obj->flags |= RTEMS_RTL_OBJ_LOCKED;
+    rtems_rtl_unlock ();
+    rtems_rtl_obj_run_dtors (obj);
+    rtems_rtl_lock ();
+    obj->flags &= ~RTEMS_RTL_OBJ_LOCKED;
+
+    ok = rtems_rtl_obj_unload (obj);
+  }
+
+  return ok;
+}
+
+void
+rtems_rtl_run_ctors (rtems_rtl_obj_t* obj)
+{
+  rtems_rtl_obj_run_ctors (obj);
+}
+
+static bool
+rtems_rtl_path_update (bool prepend, const char* path)
+{
+  char*       paths;
+  const char* src = NULL;
+  char*       dst;
+  int         len;
+
+  if (!rtems_rtl_lock ())
+    return false;
+
+  len = strlen (path);
+
+  if (rtl->paths)
+    len += strlen (rtl->paths) + 1;
+  else
+    prepend = true;
+
+  paths = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT, len + 1, false);
+
+  if (!paths)
+  {
+    rtems_rtl_unlock ();
+    return false;
+  }
+
+  dst = paths;
+
+  if (prepend)
+  {
+    len = strlen (path);
+    src = path;
+  }
+  else if (rtl->paths)
+  {
+    len = strlen (rtl->paths);
+    src = rtl->paths;
+  }
+
+  memcpy (dst, src, len);
+
+  dst += len;
+
+  if (rtl->paths)
+  {
+    *dst = ':';
+    ++dst;
+  }
+
+  if (prepend)
+  {
+    src = rtl->paths;
+    if (src)
+      len = strlen (src);
+  }
+  else
+  {
+    len = strlen (path);
+    src = path;
+  }
+
+  if (src)
+  {
+    memcpy (dst, src, len);
+    dst += len;
+  }
+
+  *dst = '\0';
+
+  rtl->paths = paths;
+
+  rtems_rtl_unlock ();
+  return false;
+}
+
+bool
+rtems_rtl_path_append (const char* path)
+{
+  return rtems_rtl_path_update (false, path);
+}
+
+bool
+rtems_rtl_path_prepend (const char* path)
+{
+  return rtems_rtl_path_update (true, path);
+}
+
+void
+rtems_rtl_base_sym_global_add (const unsigned char* esyms,
+                               unsigned int         size)
+{
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_GLOBAL_SYM))
+    printf ("rtl: adding global symbols, table size %u\n", size);
+
+  if (!rtems_rtl_lock ())
+  {
+    rtems_rtl_set_error (EINVAL, "global add cannot lock rtl");
+    return;
+  }
+
+  rtems_rtl_symbol_global_add (rtl->base, esyms, size);
+
+  rtems_rtl_unlock ();
+}
+
+rtems_rtl_obj_t*
+rtems_rtl_baseimage (void)
+{
+  return NULL;
+}
diff --git a/cpukit/libdl/rtl.h b/cpukit/libdl/rtl.h
new file mode 100644
index 0000000..d0a0d00
--- /dev/null
+++ b/cpukit/libdl/rtl.h
@@ -0,0 +1,320 @@
+/*
+ *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker
+ *
+ * This is the POSIX interface to run-time loading of code into RTEMS.
+ */
+
+#if !defined (_RTEMS_RTL_H_)
+#define _RTEMS_RTL_H_
+
+#include <link.h>
+#include <rtems.h>
+#include <rtems/chain.h>
+
+#include <rtems/rtl/rtl-allocator.h>
+#include <rtems/rtl/rtl-fwd.h>
+#include <rtems/rtl/rtl-obj.h>
+#include <rtems/rtl/rtl-obj-cache.h>
+#include <rtems/rtl/rtl-obj-comp.h>
+#include <rtems/rtl/rtl-unresolved.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup rtems_rtl RTEMS Runtime Link Editor
+ *
+ * The module implements a runtime link editor with the standard dlopen, and
+ * dlclose family of functions.
+ *
+ * The runtime link editor is different to that found on Unix type systems. The
+ * object modules are compiled for PIC or position indepentent code and
+ * therefore require relocating when loaded.
+ *
+ * The object file format is currently ELF and object files can be separate
+ * files or in an archive. Object files in an archive are referenced by
+ * specifing 'archive:object' format. For example 'libfoo.a:bar.o'.
+ */
+
+/**
+ * Macros to glue two tokens.
+ */
+#ifdef __STDC__
+#define RTL_XGLUE(a,b) a##b
+#else
+#define RTL_XGLUE(a,b) a/**/b
+#endif
+
+#define RTL_GLUE(a,b) RTL_XGLUE(a,b)
+
+/**
+ * The number of buckets in the global symbol table.
+ */
+#define RTEMS_RTL_SYMS_GLOBAL_BUCKETS (32)
+
+/**
+ * The number of relocation record per block in the unresolved table.
+ */
+#define RTEMS_RTL_UNRESOLVED_BLOCK_SIZE (64)
+
+/**
+ * The global debugger interface variable.
+ */
+extern struct r_debug _rtld_debug;
+
+/**
+ * Debugger break function. Call when debugging to have it read the _rtld_debug
+ * variable.
+ */
+extern void _rtld_debug_state (void);
+
+/**
+ * The type of constructor/destructor function.
+ */
+typedef void (*rtems_rtl_cdtor_t)(void);
+
+/**
+ * The global RTL data. This structure is allocated on the heap when the first
+ * call to the RTL is made and never released.
+ *
+ * The global symbol table is a hash table held in this structure and the
+ * actual symbols are part of the object's structure. If this is a problem we
+ * could look at a hash table per object file.
+ */
+struct rtems_rtl_data_s
+{
+  rtems_id               lock;           /**< The RTL lock id */
+  rtems_rtl_alloc_data_t allocator;      /**< The allocator data. */
+  rtems_chain_control    objects;        /**< List if loaded object files. */
+  const char*            paths;          /**< Search paths for archives. */
+  rtems_rtl_symbols_t    globals;        /**< Global symbol table. */
+  rtems_rtl_unresolved_t unresolved;     /**< Unresolved symbols. */
+  rtems_rtl_obj_t*       base;           /**< Base object file. */
+  rtems_rtl_obj_cache_t  symbols;        /**< Symbols object file cache. */
+  rtems_rtl_obj_cache_t  strings;        /**< Strings object file cache. */
+  rtems_rtl_obj_cache_t  relocs;         /**< Relocations object file cache. */
+  rtems_rtl_obj_comp_t   decomp;         /**< The decompression compressor. */
+  int                    last_errno;     /**< Last error number. */
+  char                   last_error[64]; /**< Last error string. */
+};
+
+/**
+ * Get the RTL data with out locking. This call assmes the RTL is locked.
+ *
+ * @return rtems_rtl_data_t* The RTL data after being locked.
+ * @retval NULL The RTL data is not initialised.
+ */
+rtems_rtl_data_t* rtems_rtl_data (void);
+
+/**
+ * Get the RTL global symbol table with out locking. This call assmes the RTL
+ * is locked.
+ *
+ * @return rtems_rtl_symbols_t* The RTL global symbols after being locked.
+ * @retval NULL The RTL data is not initialised.
+ */
+rtems_rtl_symbols_t* rtems_rtl_global_symbols (void);
+
+/**
+ * Get the RTL resolved table with out locking. This call assmes the RTL
+ * is locked.
+ *
+ * @return rtems_rtl_unresolv_t* The RTL unresolved symbols and reloc records.
+ * @retval NULL The RTL data is not initialised.
+ */
+rtems_rtl_unresolved_t* rtems_rtl_unresolved (void);
+
+/**
+ * Get the RTL symbols, strings, or relocations object file caches. This call
+ * assmes the RTL is locked.
+ *
+ * @param symbols Pointer to the location to set the cache into. Returns NULL
+ *                is rtl is not initialised. If NULL is passed in no value set.
+ * @param strings Pointer to the location to set the cache into. Returns NULL
+ *                is rtl is not initialised. If NULL is passed in no value set.
+ * @param relocs Pointer to the location to set the cache into. Returns NULL
+ *               is rtl is not initialised. If NULL is passed in no value set.
+ */
+void rtems_rtl_obj_caches (rtems_rtl_obj_cache_t** symbols,
+                           rtems_rtl_obj_cache_t** strings,
+                           rtems_rtl_obj_cache_t** relocs);
+
+/**
+ * Flush all the object file caches.
+ */
+void rtems_rtl_obj_caches_flush (void);
+
+/**
+ * Get the RTL decompressor setting the cache and the offset in the file the
+ * compressed stream starts. This call assmes the RTL is locked.
+ *
+ * @param decomp Pointer to the location to set the compressor into. Returns
+ *               NULL is rtl is not initialised.
+ * @param cache The cache to read the file with. Saves needing an extrs buffer.
+ * @param offset The offset in the file the compressed stream starts.
+ */
+void rtems_rtl_obj_comp (rtems_rtl_obj_comp_t** decomp,
+                         rtems_rtl_obj_cache_t* cache,
+                         int                    fd,
+                         int                    compression,
+                         off_t                  offset);
+
+/**
+ * Lock the Run-time Linker.
+ *
+ * @return rtems_rtl_data_t* The RTL data after being locked.
+ * @retval NULL The RTL data could not be initialised or locked. Typically this
+ *              means the lock could not be created.
+ */
+rtems_rtl_data_t* rtems_rtl_lock (void);
+
+/**
+ * Unlock the Run-time Linker.
+ *
+ * @return True The RTL is unlocked.
+ * @return False The RTL could not be unlocked. Not much you can do.
+ */
+bool rtems_rtl_unlock (void);
+
+/**
+ * Check a pointer is a valid object file descriptor returning the pointer as
+ * that type.
+ *
+ * Assumes the RTL has been locked.
+ *
+ * @param handle Pointer to the object file to be validated.
+ * @return rtl_obj* The object file descriptor. NULL is returned if invalid.
+ */
+rtems_rtl_obj_t* rtems_rtl_check_handle (void* handle);
+
+/**
+ * Find the object given a file name.
+ *
+ * @param name The name of the object file.
+ * @retval NULL No object file with that name found.
+ * @return rtems_rtl_obj_t* The object file descriptor.
+ */
+rtems_rtl_obj_t* rtems_rtl_find_obj (const char* name);
+
+/**
+ * Load an object file into memory relocating it. It will not be resolved
+ * against other symbols in other object files or the base image.
+ *
+ * The name can be a file name for an object file or it can be encoded to
+ * reference an archive of object modules (static library). This encoding is
+ * specific to RTEMS and allows dependences to specify an archive without the
+ * searching overhead normally incurred by linkers locating object files in an
+ * archive. The file name format rules are:
+ *
+ *  1. Absolute file references a specific object file in the architecture
+ *     specific location on the file system.
+ *
+ *  2. Relative file references an object format file in the search path.
+ *
+ *  3. Absolute archive and file reference to a specific location in the file
+ *     system. The archive and file are encoded as 'archive:file [@offset]'
+ *     where 'archive' is a valid file at the absolute path in the file system,
+ *     and 'file' is a contained in the archive, and optionally an offset to
+ *     the 'file' in the 'archive'. If no offset is provided the archive is
+ *     searched.
+ *
+ *  4. Relative archive and file in the search path. The encoding is the same
+ *     as described in item 3 of this list.
+ *
+ * Assumes the RTL has been locked.
+ *
+ * @param name The name of the object file.
+ * @param mode The mode of the load as defined by the dlopen call.
+ * @return rtl_obj* The object file descriptor. NULL is returned if the load fails.
+ */
+rtems_rtl_obj_t* rtems_rtl_load_object (const char* name, int mode);
+
+/**
+ * Unload an object file. This only happens when the user count is 0.
+ *
+ * Assumes the RTL has been locked.
+ *
+ * @param obj The object file descriptor.
+ * @retval true The object file has been unloaded.
+ * @retval false The object file could not be unloaded.
+ */
+bool rtems_rtl_unload_object (rtems_rtl_obj_t* obj);
+
+/**
+ * Run any constructor functions the object file may contain. This call
+ * assumes the linker is unlocked.
+ *
+ * @param obj The object file.
+ */
+void rtems_rtl_run_ctors (rtems_rtl_obj_t* obj);
+
+/**
+ * Get the last error message clearing it. This operation locks the run time
+ * linker and therefore keeps the RTL thread safe but this call is not thread
+ * safe is multiple threads are loading object files at the same time. This
+ * call is provided to map to the dlopen family of calls.
+ *
+ * @param message Pointer to a buffer to copy the message into.
+ * @param max_message The maximum message that can be copied.
+ * @return int The last error number.
+ */
+int rtems_rtl_get_error (char* message, size_t max_message);
+
+/**
+ * Append the path to the search path.
+ *
+ * @path The path to append.
+ * @retval false The path could not be appended.
+ * @retval true The path was appended.
+ */
+bool rtems_rtl_path_append (const char* path);
+
+/**
+ * Prepend the path to the search path.
+ *
+ * @path The path to prepend.
+ * @retval false The path could not be prepended.
+ * @retval true The path was prepended.
+ */
+
+bool rtems_rtl_path_prepend (const char* path);
+
+/**
+ * Add an exported symbol table to the global symbol table. This call is
+ * normally used by an object file when loaded that contains a global symbol
+ * table.
+ *
+ * @param esyms The exported symbol table.
+ * @param count The size of the exported symbol table.
+ */
+void rtems_rtl_base_sym_global_add (const unsigned char* esyms,
+                                    unsigned int         count);
+
+/**
+ * Return the object file descriptor for the base image. The object file
+ * descriptor returned is created when the run time linker is initialised.
+ *
+ * Assumes the RTL has been locked.
+ *
+ * @return rtl_obj* The object file descriptor for the base image. NULL is
+ *                  returned if the load fails.
+ */
+rtems_rtl_obj_t* rtems_rtl_baseimage (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/preinstall.am b/cpukit/preinstall.am
index 1d9cd53..4a6c25b 100644
--- a/cpukit/preinstall.am
+++ b/cpukit/preinstall.am
@@ -46,7 +46,6 @@ $(PROJECT_INCLUDE)/utf8proc/utf8proc.h: libmisc/utf8proc/utf8proc.h $(PROJECT_IN
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/utf8proc/utf8proc.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/utf8proc/utf8proc.h
 
-if NEWLIB
 $(PROJECT_INCLUDE)/sys/$(dirstamp):
 	@$(MKDIR_P) $(PROJECT_INCLUDE)/sys
 	@: > $(PROJECT_INCLUDE)/sys/$(dirstamp)
@@ -130,6 +129,92 @@ $(PROJECT_INCLUDE)/rtems/bsdnet/_types.h: libnetworking/rtems/bsdnet/_types.h $(
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/bsdnet/_types.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/bsdnet/_types.h
 endif
+if LIBDL
+$(PROJECT_INCLUDE)/dlfcn.h: libdl/dlfcn.h $(PROJECT_INCLUDE)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/dlfcn.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/dlfcn.h
+
+$(PROJECT_INCLUDE)/link.h: libdl/include/link.h $(PROJECT_INCLUDE)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/link.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/link.h
+
+$(PROJECT_INCLUDE)/link_elf.h: libdl/include/link_elf.h $(PROJECT_INCLUDE)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/link_elf.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/link_elf.h
+
+$(PROJECT_INCLUDE)/sys/cdefs_elf.h: libdl/include/sys/cdefs_elf.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/cdefs_elf.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/cdefs_elf.h
+
+$(PROJECT_INCLUDE)/sys/exec_elf.h: libdl/include/sys/exec_elf.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/exec_elf.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/exec_elf.h
+
+$(PROJECT_INCLUDE)/machine/$(dirstamp):
+	@$(MKDIR_P) $(PROJECT_INCLUDE)/machine
+	@: > $(PROJECT_INCLUDE)/machine/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/machine/$(dirstamp)
+
+$(PROJECT_INCLUDE)/machine/elf_machdep.h: libdl/include/arch/@RTEMS_CPU@/machine/elf_machdep.h $(PROJECT_INCLUDE)/machine/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/machine/elf_machdep.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/machine/elf_machdep.h
+
+$(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp):
+	@$(MKDIR_P) $(PROJECT_INCLUDE)/rtems/rtl
+	@: > $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/rtl/dlfcn-shell.h: libdl/dlfcn-shell.h $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/dlfcn-shell.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/dlfcn-shell.h
+
+$(PROJECT_INCLUDE)/rtems/rtl/rtl.h: libdl/rtl.h $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rtl.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rtl.h
+
+$(PROJECT_INCLUDE)/rtems/rtl/rtl-allocator.h: libdl/rtl-allocator.h $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rtl-allocator.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rtl-allocator.h
+
+$(PROJECT_INCLUDE)/rtems/rtl/rtl-obj-fwd.h: libdl/rtl-obj-fwd.h $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rtl-obj-fwd.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rtl-obj-fwd.h
+
+$(PROJECT_INCLUDE)/rtems/rtl/rtl-fwd.h: libdl/rtl-fwd.h $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rtl-fwd.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rtl-fwd.h
+
+$(PROJECT_INCLUDE)/rtems/rtl/rtl-obj.h: libdl/rtl-obj.h $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rtl-obj.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rtl-obj.h
+
+$(PROJECT_INCLUDE)/rtems/rtl/rtl-obj-cache.h: libdl/rtl-obj-cache.h $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rtl-obj-cache.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rtl-obj-cache.h
+
+$(PROJECT_INCLUDE)/rtems/rtl/rtl-obj-comp.h: libdl/rtl-obj-comp.h $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rtl-obj-comp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rtl-obj-comp.h
+
+$(PROJECT_INCLUDE)/rtems/rtl/rtl-unresolved.h: libdl/rtl-unresolved.h $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rtl-unresolved.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rtl-unresolved.h
+
+$(PROJECT_INCLUDE)/rtems/rtl/rtl-indirect-ptr.h: libdl/rtl-indirect-ptr.h $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rtl-indirect-ptr.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rtl-indirect-ptr.h
+
+$(PROJECT_INCLUDE)/rtems/rtl/rtl-sym.h: libdl/rtl-sym.h $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rtl-sym.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rtl-sym.h
+
+$(PROJECT_INCLUDE)/rtems/rtl/rap.h: libdl/rap.h $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rap.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rap.h
+
+$(PROJECT_INCLUDE)/rtems/rtl/rap-shell.h: libdl/rap-shell.h $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rap-shell.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rap-shell.h
 endif
 $(PROJECT_INCLUDE)/rtems/bspIo.h: include/rtems/bspIo.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/bspIo.h
diff --git a/cpukit/wrapup/Makefile.am b/cpukit/wrapup/Makefile.am
index e89426f..bf38cca 100644
--- a/cpukit/wrapup/Makefile.am
+++ b/cpukit/wrapup/Makefile.am
@@ -77,6 +77,10 @@ if NEWLIB
 TMP_LIBS += ../libmd/libmd.a
 endif
 
+if LIBDL
+TMP_LIBS += ../libdl/libdl.a
+endif
+
 librtemscpu.a: $(TMP_LIBS)
 	rm -f $@
 	$(MKDIR_P) $(ARCH)
diff --git a/testsuites/libtests/Makefile.am b/testsuites/libtests/Makefile.am
index 847cd2a..179c123 100644
--- a/testsuites/libtests/Makefile.am
+++ b/testsuites/libtests/Makefile.am
@@ -14,7 +14,7 @@ _SUBDIRS += block14
 _SUBDIRS += block13
 _SUBDIRS += rbheap01
 _SUBDIRS += flashdisk01
-_SUBDIRS += capture01 
+_SUBDIRS += capture01
 
 _SUBDIRS += bspcmdline01 cpuuse devfs01 devfs02 devfs03 devfs04 \
     deviceio01 devnullfatal01 dumpbuf01 gxx01 top\
@@ -36,5 +36,9 @@ _SUBDIRS += ftp01
 _SUBDIRS += syscall01
 endif
 
+if DLTESTS
+_SUBDIRS += dl01
+endif
+
 include $(top_srcdir)/../automake/test-subdirs.am
 include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/libtests/configure.ac b/testsuites/libtests/configure.ac
index 410fb75..9914a06 100644
--- a/testsuites/libtests/configure.ac
+++ b/testsuites/libtests/configure.ac
@@ -41,6 +41,29 @@ AM_CONDITIONAL([HAS_COMPLEX],[test "$ac_cv_header_complex_h" = yes])
 AM_CONDITIONAL(NETTESTS,test "$rtems_cv_RTEMS_NETWORKING" = "yes")
 AM_CONDITIONAL(HAS_POSIX,test x"${rtems_cv_RTEMS_POSIX_API}" = x"yes")
 
+# Must match the list in cpukit.
+AC_MSG_CHECKING([whether CPU supports libdl])
+case $RTEMS_CPU in
+  arm | bfin | h8300 | i386 | lm32 | m32r | m68k | mips | \
+  moxie | nios2 | powerpc | sparc | v850)
+   HAVE_LIBDL=yes ;;
+  *)
+   HAVE_LIBDL=no ;;
+esac
+AM_CONDITIONAL(DLTESTS,[test x"$HAVE_LIBDL" = x"yes"])
+AC_MSG_RESULT([$HAVE_LIBDL])
+
+AS_IF([test x"$HAVE_LIBDL" = x"yes"],[
+  AC_CHECK_PROG(RTEMS_LD_CHECK,rtems-ld,yes)
+  if test x"$RTEMS_LD_CHECK" != x"yes" ; then
+    AC_MSG_ERROR([Please install rtems-tools.])
+  fi
+  AC_CHECK_PROG(RTEMS_SYMS_CHECK,rtems-syms,yes)
+  if test x"$RTEMS_SYMS_CHECK" != x"yes" ; then
+    AC_MSG_ERROR([Please install rtems-tools.])
+  fi
+])
+
 # Explicitly list all Makefiles here
 AC_CONFIG_FILES([Makefile
 newlib01/Makefile
@@ -78,6 +101,7 @@ devfs03/Makefile
 devfs04/Makefile
 deviceio01/Makefile
 devnullfatal01/Makefile
+dl01/Makefile
 dumpbuf01/Makefile
 ftp01/Makefile
 gxx01/Makefile
diff --git a/testsuites/libtests/dl01/Makefile.am b/testsuites/libtests/dl01/Makefile.am
new file mode 100644
index 0000000..df62d60
--- /dev/null
+++ b/testsuites/libtests/dl01/Makefile.am
@@ -0,0 +1,43 @@
+rtems_tests_PROGRAMS = dl01
+dl01_SOURCES = init.c dl-load.c dl-tar.c dl-tar.h
+
+BUILT_SOURCES = dl-tar.c dl-tar.h
+
+dist_rtems_tests_DATA = dl01.scn dl01.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(dl01_OBJECTS)
+LINK_LIBS = $(dl01_LDLIBS)
+
+dl-o1.o: dl-o1.c
+
+dl.tar: dl-o1.o
+	@rm -f $@
+	$(PAX) -w -f $@ $<
+
+dl-tar.c: dl.tar
+	$(BIN2C) -C $< $@
+CLEANFILES += dl-tar.c
+
+dl-tar.h: dl.tar
+	$(BIN2C) -H $< $@
+CLEANFILES += dl-tar.h
+
+dl01.pre$(EXEEXT): $(dl01_OBJECTS) $(dl01_DEPENDENCIES)
+	@rm -f dl01.pre$(EXEEXT)
+	$(make-exe)
+
+dl-sym.o: dl01.pre$(EXEEXT)
+	rtems-syms -e -c "$(CFLAGS)" -o $@ $<
+
+dl01$(EXEEXT):  $(dl01_OBJECTS) $(dl01_DEPENDENCIES) dl-sym.o
+	@rm -f dl01$(EXEEXT)
+	$(LINK.c) $(CPU_CFLAGS) $(AM_CFLAGS) $(AM_LDFLAGS) \
+		    -o $(basename $@)$(EXEEXT) $(LINK_OBJS) dl-sym.o $(LINK_LIBS)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/libtests/dl01/dl-load.c b/testsuites/libtests/dl01/dl-load.c
new file mode 100644
index 0000000..cd63cc5
--- /dev/null
+++ b/testsuites/libtests/dl01/dl-load.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2014 Chris Johns <chrisj at rtems.org>.  All rights reserved.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <stdio.h>
+
+#include <dlfcn.h>
+
+#include "dl-load.h"
+
+typedef int (*call_t)(int argc, char* argv[]);
+
+
+static const char* call_1[] = { "Line 1", "Line 2" };
+static const char* call_2[] = { "Call 2, line 1",
+                                "Call 2, line 2",
+                                "Call 2, line 3" };
+
+int dl_load_test(void)
+{
+  void*  handle;
+  call_t call;
+  int    call_ret;
+  int    unresolved;
+  char*  message = "loaded";
+
+  printf("load: /dl-o1.o\n");
+
+  handle = dlopen ("/dl-o1.o", RTLD_NOW | RTLD_GLOBAL);
+  if (!handle)
+  {
+    printf("dlopen failed: %s\n", dlerror());
+    return 1;
+  }
+
+  if (dlinfo (handle, RTLD_DI_UNRESOLVED, &unresolved) < 0)
+    message = "dlinfo error checking unresolved status";
+  else if (unresolved)
+    message = "has unresolved externals";
+
+  printf ("handle: %p %s\n", handle, message);
+
+  call = dlsym (handle, "rtems_main");
+  if (call == NULL)
+  {
+    printf("dlsym failed: symbol not found\n");
+    return 1;
+  }
+
+  call_ret = call (2, call_1);
+  if (call_ret != 2)
+  {
+    printf("dlsym call failed: ret value bad\n");
+    return 1;
+  }
+
+  call_ret = call (3, call_2);
+  if (call_ret != 3)
+  {
+    printf("dlsym call failed: ret value bad\n");
+    return 1;
+  }
+
+  if (dlclose (handle) < 0)
+  {
+    printf("dlclose failed: %s\n", dlerror());
+    return 1;
+  }
+
+  printf ("handle: %p closed\n", handle);
+
+  return 0;
+}
diff --git a/testsuites/libtests/dl01/dl-load.h b/testsuites/libtests/dl01/dl-load.h
new file mode 100644
index 0000000..3f3910a
--- /dev/null
+++ b/testsuites/libtests/dl01/dl-load.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2014 Chris Johns <chrisj at rtems.org>.  All rights reserved.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if !defined(_DL_LOAD_H_)
+#define _DL_LOAD_H_
+
+int dl_load_test(void);
+
+#endif
diff --git a/testsuites/libtests/dl01/dl-o1.c b/testsuites/libtests/dl01/dl-o1.c
new file mode 100644
index 0000000..6e7bb8a
--- /dev/null
+++ b/testsuites/libtests/dl01/dl-o1.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2014 Chris Johns <chrisj at rtems.org>.  All rights reserved.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/**
+ * Hello World as a loadable module.
+ */
+
+#include <stdio.h>
+
+/*
+ * Yes a decl in the source. This is a modules main and I could not find which
+ * header main is defined in.
+ */
+int rtems_main (int argc, char* argv[]);
+
+int rtems_main (int argc, char* argv[])
+{
+  int arg;
+  printf("Loaded module: argc:%d [%s]\n", argc, __FILE__);
+  for (arg = 0; arg < argc; ++arg)
+    printf("  %d: %s\n", arg, argv[arg]);
+  return argc;
+}
diff --git a/testsuites/libtests/dl01/dl01.doc b/testsuites/libtests/dl01/dl01.doc
new file mode 100644
index 0000000..e69de29
diff --git a/testsuites/libtests/dl01/dl01.scn b/testsuites/libtests/dl01/dl01.scn
new file mode 100644
index 0000000..e69de29
diff --git a/testsuites/libtests/dl01/init.c b/testsuites/libtests/dl01/init.c
new file mode 100644
index 0000000..d667502
--- /dev/null
+++ b/testsuites/libtests/dl01/init.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2014 Chris Johns <chrisj at rtems.org>.  All rights reserved.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include "tmacros.h"
+
+#include <errno.h>
+#include <string.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include <rtems/rtl/rtl.h>
+#include <rtems/untar.h>
+
+#include "dl-load.h"
+
+const char rtems_test_name[] = "libdl (RTL) Loader 1";
+
+/* forward declarations to avoid warnings */
+static rtems_task Init(rtems_task_argument argument);
+
+#include "dl-tar.h"
+
+#define TARFILE_START dl_tar
+#define TARFILE_SIZE  dl_tar_size
+
+static int test(void)
+{
+  int ret;
+  ret = dl_load_test();
+  if (ret)
+    rtems_test_exit(ret);
+  return 0;
+}
+
+static void Init(rtems_task_argument arg)
+{
+  int te;
+
+  TEST_BEGIN();
+
+  te = Untar_FromMemory((void *)TARFILE_START, (size_t)TARFILE_SIZE);
+  if (te != 0)
+  {
+    printf("untar failed: %d\n", te);
+    rtems_test_exit(1);
+    exit (1);
+  }
+
+  test();
+
+  TEST_END();
+
+  rtems_test_exit(0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 4
+
+#define CONFIGURE_MAXIMUM_TASKS 1
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE (8U * 1024U)
+
+#define CONFIGURE_EXTRA_TASK_STACKS (8 * 1024)
+
+#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
+



More information about the vc mailing list