summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2012-04-25 10:12:19 +1000
committerChris Johns <chrisj@rtems.org>2012-04-25 10:12:19 +1000
commit673b40c95705127635af12bda15694fd6ab5a96b (patch)
tree5c243823cf495ba3702773f94b275a442ac218de
Import the current project to git.
-rw-r--r--WAF-README42
-rw-r--r--dlfcn-shell.c118
-rw-r--r--dlfcn.c155
-rw-r--r--images/icons/README5
-rw-r--r--images/icons/callouts/1.pngbin0 -> 329 bytes
-rw-r--r--images/icons/callouts/10.pngbin0 -> 361 bytes
-rw-r--r--images/icons/callouts/11.pngbin0 -> 565 bytes
-rw-r--r--images/icons/callouts/12.pngbin0 -> 617 bytes
-rw-r--r--images/icons/callouts/13.pngbin0 -> 623 bytes
-rw-r--r--images/icons/callouts/14.pngbin0 -> 411 bytes
-rw-r--r--images/icons/callouts/15.pngbin0 -> 640 bytes
-rw-r--r--images/icons/callouts/2.pngbin0 -> 353 bytes
-rw-r--r--images/icons/callouts/3.pngbin0 -> 350 bytes
-rw-r--r--images/icons/callouts/4.pngbin0 -> 345 bytes
-rw-r--r--images/icons/callouts/5.pngbin0 -> 348 bytes
-rw-r--r--images/icons/callouts/6.pngbin0 -> 355 bytes
-rw-r--r--images/icons/callouts/7.pngbin0 -> 344 bytes
-rw-r--r--images/icons/callouts/8.pngbin0 -> 357 bytes
-rw-r--r--images/icons/callouts/9.pngbin0 -> 357 bytes
-rw-r--r--images/icons/caution.pngbin0 -> 2734 bytes
-rw-r--r--images/icons/example.pngbin0 -> 2599 bytes
-rw-r--r--images/icons/home.pngbin0 -> 1340 bytes
-rw-r--r--images/icons/important.pngbin0 -> 2980 bytes
-rw-r--r--images/icons/next.pngbin0 -> 1302 bytes
-rw-r--r--images/icons/note.pngbin0 -> 2494 bytes
-rw-r--r--images/icons/prev.pngbin0 -> 1348 bytes
-rw-r--r--images/icons/tip.pngbin0 -> 2718 bytes
-rw-r--r--images/icons/up.pngbin0 -> 1320 bytes
-rw-r--r--images/icons/warning.pngbin0 -> 3214 bytes
-rw-r--r--images/rtemswhitebg.jpgbin0 -> 117890 bytes
-rw-r--r--init.c222
-rw-r--r--libbsd/include/arch/i386/machine/ansi.h77
-rw-r--r--libbsd/include/arch/i386/machine/asm.h220
-rw-r--r--libbsd/include/arch/i386/machine/cdefs.h8
-rw-r--r--libbsd/include/arch/i386/machine/elf_machdep.h63
-rw-r--r--libbsd/include/arch/i386/machine/int_types.h66
-rw-r--r--libbsd/include/arch/m68k/machine/ansi.h104
-rw-r--r--libbsd/include/arch/m68k/machine/asm.h232
-rw-r--r--libbsd/include/arch/m68k/machine/cdefs.h8
-rw-r--r--libbsd/include/arch/m68k/machine/elf_machdep.h47
-rw-r--r--libbsd/include/arch/m68k/machine/int_types.h70
-rw-r--r--libbsd/include/arch/nios2/machine/ansi.h104
-rw-r--r--libbsd/include/arch/nios2/machine/asm.h219
-rw-r--r--libbsd/include/arch/nios2/machine/cdefs.h8
-rw-r--r--libbsd/include/arch/nios2/machine/elf_machdep.h46
-rw-r--r--libbsd/include/arch/nios2/machine/int_types.h70
-rw-r--r--libbsd/include/arch/sparc/machine/ansi.h78
-rw-r--r--libbsd/include/arch/sparc/machine/asm.h208
-rw-r--r--libbsd/include/arch/sparc/machine/cdefs.h8
-rw-r--r--libbsd/include/arch/sparc/machine/elf_machdep.h92
-rw-r--r--libbsd/include/arch/sparc/machine/int_types.h85
-rw-r--r--libbsd/include/dlfcn.h112
-rw-r--r--libbsd/include/err.h83
-rw-r--r--libbsd/include/link.h45
-rw-r--r--libbsd/include/link_elf.h36
-rw-r--r--libbsd/include/sys/ansi.h63
-rw-r--r--libbsd/include/sys/cdefs.h363
-rw-r--r--libbsd/include/sys/cdefs_elf.h152
-rw-r--r--libbsd/include/sys/exec_elf.h1093
-rw-r--r--libbsd/include/sys/featuretest.h73
-rw-r--r--libbsd/include/sys/nb-queue.h665
-rw-r--r--main.c463
-rw-r--r--mcf5235-gdbinit-script58
-rw-r--r--mksyms.awk115
-rw-r--r--mmap-internal.h37
-rw-r--r--mmap.c235
-rw-r--r--munmap.c73
-rw-r--r--networkconfig.h162
-rw-r--r--pc386-gdb.c39
-rw-r--r--pc386-gdb.h18
-rw-r--r--pc586-gdbinit-script12
-rw-r--r--pkgconfig.py79
-rw-r--r--pkgconfig.pycbin0 -> 2612 bytes
-rwxr-xr-xrtems-grub-h0-1.cfg9
-rw-r--r--rtems-rtl.txt310
-rw-r--r--rtems.py392
-rw-r--r--rtl-chain-iterator.c59
-rw-r--r--rtl-chain-iterator.h61
-rw-r--r--rtl-debugger.c41
-rw-r--r--rtl-elf.c605
-rw-r--r--rtl-elf.h129
-rw-r--r--rtl-error.c49
-rw-r--r--rtl-error.h46
-rw-r--r--rtl-fwd.h35
-rw-r--r--rtl-mdreloc-arm.c153
-rw-r--r--rtl-mdreloc-i386.c99
-rw-r--r--rtl-mdreloc-m68k.c104
-rw-r--r--rtl-mdreloc-nios2.c46
-rw-r--r--rtl-mdreloc-powerpc.c155
-rw-r--r--rtl-mdreloc-sparc.c256
-rw-r--r--rtl-obj-cache.c178
-rw-r--r--rtl-obj-cache.h131
-rw-r--r--rtl-obj-fwd.h41
-rw-r--r--rtl-obj.c1040
-rw-r--r--rtl-obj.h423
-rw-r--r--rtl-shell.c314
-rw-r--r--rtl-shell.h41
-rw-r--r--rtl-sym.c231
-rw-r--r--rtl-sym.h122
-rw-r--r--rtl-trace.c133
-rw-r--r--rtl-trace.h99
-rw-r--r--rtl.c520
-rw-r--r--rtl.h273
-rw-r--r--rtld-gsyms.c1
-rw-r--r--shell-init3
-rw-r--r--sys/mman.h185
-rw-r--r--wscript142
-rw-r--r--x-long-name-to-create-gnu-extension-in-archive.c44
-rw-r--r--x.h7
-rw-r--r--xa.c9
110 files changed, 12817 insertions, 0 deletions
diff --git a/WAF-README b/WAF-README
new file mode 100644
index 0000000..9bbb79f
--- /dev/null
+++ b/WAF-README
@@ -0,0 +1,42 @@
+RTEMS Waf Build Module.
+
+ Chris Johns <chrisj@rtems.org>
+
+Background
+
+Waf is a build tool that manages all aspects of building software. You can find
+waf here:
+
+ http://waf.googlecode.com/
+
+I suggest you read the Waf Book to find about waf and what it does. It is fast,
+easy to program and additive. It uses Python as the scripting language so the
+build scripts require a Python syntax. It also allows you to use the power of
+Python and its full programming language to implement a build system with the
+same approach you design the software you embed on RTEMS. Just because it is a
+build system does not mean you are limited to using design techniques, tools
+and scripting formats from 30 years ago.
+
+RTEMS Module
+
+The rtems.py and pkgconfig.py provide the support you need. Place these files
+in the top of your source tree where you will add your wscript file. You need
+to add a wscript. This example is for a simple hello world program (source not
+provided):
+
+ import rtems
+
+ def init(ctx):
+ rtems.init(ctx)
+
+ def options(opt):
+ rtems.options(opt)
+
+ def configure(conf):
+ rtems.configure(conf)
+
+ def build(bld):
+ rtems.build(bld)
+ bld.program(target = 'hello-world',
+ features = 'cprogram',
+ source = 'main.c')
diff --git a/dlfcn-shell.c b/dlfcn-shell.c
new file mode 100644
index 0000000..88b9dcd
--- /dev/null
+++ b/dlfcn-shell.c
@@ -0,0 +1,118 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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>
+
+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/dlfcn.c b/dlfcn.c
new file mode 100644
index 0000000..faafde2
--- /dev/null
+++ b/dlfcn.c
@@ -0,0 +1,155 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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 <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;
+}
+
+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/images/icons/README b/images/icons/README
new file mode 100644
index 0000000..f12b2a7
--- /dev/null
+++ b/images/icons/README
@@ -0,0 +1,5 @@
+Replaced the plain DocBook XSL admonition icons with Jimmac's DocBook
+icons (http://jimmac.musichall.cz/ikony.php3). I dropped transparency
+from the Jimmac icons to get round MS IE and FOP PNG incompatibilies.
+
+Stuart Rackham
diff --git a/images/icons/callouts/1.png b/images/icons/callouts/1.png
new file mode 100644
index 0000000..7d47343
--- /dev/null
+++ b/images/icons/callouts/1.png
Binary files differ
diff --git a/images/icons/callouts/10.png b/images/icons/callouts/10.png
new file mode 100644
index 0000000..997bbc8
--- /dev/null
+++ b/images/icons/callouts/10.png
Binary files differ
diff --git a/images/icons/callouts/11.png b/images/icons/callouts/11.png
new file mode 100644
index 0000000..ce47dac
--- /dev/null
+++ b/images/icons/callouts/11.png
Binary files differ
diff --git a/images/icons/callouts/12.png b/images/icons/callouts/12.png
new file mode 100644
index 0000000..31daf4e
--- /dev/null
+++ b/images/icons/callouts/12.png
Binary files differ
diff --git a/images/icons/callouts/13.png b/images/icons/callouts/13.png
new file mode 100644
index 0000000..14021a8
--- /dev/null
+++ b/images/icons/callouts/13.png
Binary files differ
diff --git a/images/icons/callouts/14.png b/images/icons/callouts/14.png
new file mode 100644
index 0000000..64014b7
--- /dev/null
+++ b/images/icons/callouts/14.png
Binary files differ
diff --git a/images/icons/callouts/15.png b/images/icons/callouts/15.png
new file mode 100644
index 0000000..0d65765
--- /dev/null
+++ b/images/icons/callouts/15.png
Binary files differ
diff --git a/images/icons/callouts/2.png b/images/icons/callouts/2.png
new file mode 100644
index 0000000..5d09341
--- /dev/null
+++ b/images/icons/callouts/2.png
Binary files differ
diff --git a/images/icons/callouts/3.png b/images/icons/callouts/3.png
new file mode 100644
index 0000000..ef7b700
--- /dev/null
+++ b/images/icons/callouts/3.png
Binary files differ
diff --git a/images/icons/callouts/4.png b/images/icons/callouts/4.png
new file mode 100644
index 0000000..adb8364
--- /dev/null
+++ b/images/icons/callouts/4.png
Binary files differ
diff --git a/images/icons/callouts/5.png b/images/icons/callouts/5.png
new file mode 100644
index 0000000..4d7eb46
--- /dev/null
+++ b/images/icons/callouts/5.png
Binary files differ
diff --git a/images/icons/callouts/6.png b/images/icons/callouts/6.png
new file mode 100644
index 0000000..0ba694a
--- /dev/null
+++ b/images/icons/callouts/6.png
Binary files differ
diff --git a/images/icons/callouts/7.png b/images/icons/callouts/7.png
new file mode 100644
index 0000000..472e96f
--- /dev/null
+++ b/images/icons/callouts/7.png
Binary files differ
diff --git a/images/icons/callouts/8.png b/images/icons/callouts/8.png
new file mode 100644
index 0000000..5e60973
--- /dev/null
+++ b/images/icons/callouts/8.png
Binary files differ
diff --git a/images/icons/callouts/9.png b/images/icons/callouts/9.png
new file mode 100644
index 0000000..a0676d2
--- /dev/null
+++ b/images/icons/callouts/9.png
Binary files differ
diff --git a/images/icons/caution.png b/images/icons/caution.png
new file mode 100644
index 0000000..9a8c515
--- /dev/null
+++ b/images/icons/caution.png
Binary files differ
diff --git a/images/icons/example.png b/images/icons/example.png
new file mode 100644
index 0000000..1199e86
--- /dev/null
+++ b/images/icons/example.png
Binary files differ
diff --git a/images/icons/home.png b/images/icons/home.png
new file mode 100644
index 0000000..37a5231
--- /dev/null
+++ b/images/icons/home.png
Binary files differ
diff --git a/images/icons/important.png b/images/icons/important.png
new file mode 100644
index 0000000..be685cc
--- /dev/null
+++ b/images/icons/important.png
Binary files differ
diff --git a/images/icons/next.png b/images/icons/next.png
new file mode 100644
index 0000000..64e126b
--- /dev/null
+++ b/images/icons/next.png
Binary files differ
diff --git a/images/icons/note.png b/images/icons/note.png
new file mode 100644
index 0000000..7c1f3e2
--- /dev/null
+++ b/images/icons/note.png
Binary files differ
diff --git a/images/icons/prev.png b/images/icons/prev.png
new file mode 100644
index 0000000..3e8f12f
--- /dev/null
+++ b/images/icons/prev.png
Binary files differ
diff --git a/images/icons/tip.png b/images/icons/tip.png
new file mode 100644
index 0000000..f087c73
--- /dev/null
+++ b/images/icons/tip.png
Binary files differ
diff --git a/images/icons/up.png b/images/icons/up.png
new file mode 100644
index 0000000..2db1ce6
--- /dev/null
+++ b/images/icons/up.png
Binary files differ
diff --git a/images/icons/warning.png b/images/icons/warning.png
new file mode 100644
index 0000000..d41edb9
--- /dev/null
+++ b/images/icons/warning.png
Binary files differ
diff --git a/images/rtemswhitebg.jpg b/images/rtemswhitebg.jpg
new file mode 100644
index 0000000..f883f2c
--- /dev/null
+++ b/images/rtemswhitebg.jpg
Binary files differ
diff --git a/init.c b/init.c
new file mode 100644
index 0000000..e6c608e
--- /dev/null
+++ b/init.c
@@ -0,0 +1,222 @@
+/*
+ * $Id$
+ */
+
+/**
+ * Configure the RTEMS initialisation.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+
+#include <rtems.h>
+
+#if !RTEMS_APP_NETWORKING
+#undef RTEMS_NETWORKING
+#endif
+
+#ifdef RTEMS_NETWORKING
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/dhcp.h>
+#endif
+
+/**
+ * Configure base RTEMS resources.
+ */
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+#define CONFIGURE_MEMORY_OVERHEAD 512
+#define CONFIGURE_MAXIMUM_TASKS rtems_resource_unlimited (10)
+#define CONFIGURE_MAXIMUM_SEMAPHORES rtems_resource_unlimited (10)
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES rtems_resource_unlimited (5)
+#define CONFIGURE_MAXIMUM_PARTITIONS rtems_resource_unlimited (2)
+#define CONFIGURE_MAXIMUM_TIMERS 10
+
+/**
+ * Configure drivers.
+ */
+#define CONFIGURE_MAXIMUM_DRIVERS 10
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+/**
+ * Configure file system and libblock.
+ */
+#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 20
+#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
+#define CONFIGURE_SWAPOUT_TASK_PRIORITY 15
+
+#if RTEMS_APP_IDEDISK
+#define CONFIGURE_BDBUF_CACHE_MEMORY_SIZE (16 * 1024 * 1024)
+#define CONFIGURE_BDBUF_MAX_READ_AHEAD_BLOCKS 2
+#define CONFIGURE_BDBUF_MAX_WRITE_BLOCKS 32
+#define CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER
+#define CONFIGURE_ATA_DRIVER_TASK_PRIORITY 14
+#endif
+
+#define CONFIGURE_FILESYSTEM_ALL
+
+/**
+ * Tell confdefs.h to provide the configuration.
+ */
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
+
+#ifdef RTEMS_NETWORKING
+
+#define CONFIGURE_NETWORK_PRIORITY 10
+
+#if pc586
+#define LIBBSDPORT 1
+#define MULTI_NETDRIVER 0
+#define NEK 0
+
+#include <rtems/pci.h>
+
+#if LIBBSDPORT
+
+#include <bsp/libbsdport_api.h>
+
+driver_t* libbsdport_netdriver_table[] =
+{
+ &libbsdport_rl_driver,
+ &libbsdport_re_driver,
+ &libbsdport_fxp_driver,
+ NULL
+};
+
+static int libbsdport_net_attach (struct rtems_bsdnet_ifconfig* ocfg, int attaching);
+
+static struct rtems_bsdnet_ifconfig libbsdport_config[] =
+{
+ { "", libbsdport_net_attach, NULL }
+};
+
+static int libbsdport_net_attach (struct rtems_bsdnet_ifconfig* ocfg, int attaching)
+{
+ int result;
+ result = pci_initialize ();
+ if (result)
+ {
+ printk ("PCI initialise failed\n");
+ return result;
+ }
+ printk ("Initialising libbsdport...\n");
+ result = libbsdport_netdriver_attach (&libbsdport_config[0], attaching);
+ if (result)
+ printk ("libbsdport failed: %d: %s\n", result, strerror (result));
+ return result;
+}
+
+#define CONFIGURE_NETWORK_DRIVER_NAME ""
+#define CONFIGURE_NETWORK_DRIVER_ATTACH libbsdport_net_attach
+
+#elif MULTI_NETDRIVER
+
+int rtems_fxp_attach(struct rtems_bsdnet_ifconfig *config, int attaching);
+int rtems_3c509_driver_attach (struct rtems_bsdnet_ifconfig *, int);
+int rtems_fxp_attach (struct rtems_bsdnet_ifconfig *, int);
+int rtems_elnk_driver_attach (struct rtems_bsdnet_ifconfig *, int);
+int rtems_dec21140_driver_attach (struct rtems_bsdnet_ifconfig *, int);
+/* these don't probe and will be used even if there's no device :-( */
+int rtems_ne_driver_attach (struct rtems_bsdnet_ifconfig *, int);
+int rtems_wd_driver_attach (struct rtems_bsdnet_ifconfig *, int);
+
+static struct rtems_bsdnet_ifconfig isa_netdriver_config[] =
+{
+ { "ep0", rtems_3c509_driver_attach, isa_netdriver_config + 1 },
+ /* qemu cannot configure irq-no :-(; has it hardwired to 9 */
+ { "ne1", rtems_ne_driver_attach, 0, irno: 9 },
+};
+
+static struct rtems_bsdnet_ifconfig pci_netdriver_config[]=
+{
+ { "dc1", rtems_dec21140_driver_attach, pci_netdriver_config + 1 },
+ { "fxp1", rtems_fxp_attach, pci_netdriver_config + 2 },
+ { "elnk1", rtems_elnk_driver_attach, isa_netdriver_config },
+};
+
+extern int if_index;
+
+static int net_prober (struct rtems_bsdnet_ifconfig* ocfg, int attaching)
+{
+ struct rtems_bsdnet_ifconfig* cfg = NULL;
+ int if_index_pre;
+ if (attaching)
+ cfg = pci_initialize () ? isa_netdriver_config : pci_netdriver_config;
+
+ while ( cfg )
+ {
+ printk ("Probing %s : ", cfg->name);
+ /*
+ * Unfortunately, the return value is unreliable - some drivers report
+ * success even if they fail. Check if they chained an interface (ifnet)
+ * structure instead
+ */
+ if_index_pre = if_index;
+ cfg->attach (cfg, attaching);
+ if (if_index > if_index_pre)
+ {
+ /*
+ * Assume success.
+ */
+ printk("attached\n");
+ ocfg->name = cfg->name;
+ ocfg->attach = cfg->attach;
+ return 0;
+ }
+ printk ("Probing %s : failed\n", cfg->name);
+ cfg = cfg->next;
+ }
+ return -1;
+}
+
+#define CONFIGURE_NETWORK_DRIVER_NAME "probing"
+#define CONFIGURE_NETWORK_DRIVER_ATTACH net_prober
+#define CONFIGURE_ETHERNET_ADDRESS 0x00, 0x08, 0xc7, 0x21, 0x01, 0xf9
+#elif NEK
+int rtems_ne_driver_attach (struct rtems_bsdnet_ifconfig *, int);
+#define CONFIGURE_NETWORK_DRIVER_NAME "ne1"
+#define CONFIGURE_NETWORK_DRIVER_ATTACH rtems_ne_driver_attach
+#define CONFIGURE_ETHERNET_ADDRESS 0x00, 0x08, 0xc7, 0x21, 0x01, 0xf9
+#else
+int rtems_fxp_attach(struct rtems_bsdnet_ifconfig *config, int attaching);
+#define CONFIGURE_NETWORK_DRIVER_NAME "fxp1"
+#define CONFIGURE_NETWORK_DRIVER_ATTACH rtems_fxp_attach
+#define CONFIGURE_ETHERNET_ADDRESS 0x00, 0x08, 0xc7, 0x21, 0x01, 0xf9
+#endif
+#else
+#define CONFIGURE_NETWORK_DRIVER_NAME "fec0"
+#define CONFIGURE_NETWORK_DRIVER_ATTACH rtems_fec_driver_attach
+#define CONFIGURE_ETHERNET_ADDRESS 0x00, 0x20, 0xDD, 0xFF, 0x00, 0x01
+#endif
+
+#if RTEMS_APP_NETWORKING_DHCP
+#define CONFIGURE_NETWORK_DHCP
+#endif
+
+#if RTEMS_APP_NETWORKING_STATIC
+#define CONFIGURE_NETWORK_IPADDR "172.16.100.50"
+#define CONFIGURE_NETWORK_NETMASK "255.255.255.0"
+#define CONFIGURE_NETWORK_GATEWAY "172.16.100.1"
+#endif
+
+#define CONFIGURE_NETWORK_MBUFS (180*1024)
+#define CONFIGURE_NETWORK_MCLUSTERS (350*1024)
+
+#include "networkconfig.h"
+#endif
+
+#define CONFIGURE_SHELL_COMMANDS_INIT
+#define CONFIGURE_SHELL_COMMANDS_ALL
+#define CONFIGURE_SHELL_DEBUGRFS
+#ifdef RTEMS_NETWORKING
+#define CONFIGURE_SHELL_COMMANDS_ALL_NETWORKING
+#endif
+
+#include <rtems/shellconfig.h>
diff --git a/libbsd/include/arch/i386/machine/ansi.h b/libbsd/include/arch/i386/machine/ansi.h
new file mode 100644
index 0000000..f27e9ea
--- /dev/null
+++ b/libbsd/include/arch/i386/machine/ansi.h
@@ -0,0 +1,77 @@
+/* $NetBSD: ansi.h,v 1.23 2009/01/11 02:45:45 christos Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)ansi.h 8.2 (Berkeley) 1/4/94
+ */
+
+#ifndef _I386_ANSI_H_
+#define _I386_ANSI_H_
+
+#include <sys/cdefs.h>
+
+#include <machine/int_types.h>
+
+/*
+ * Types which are fundamental to the implementation and may appear in
+ * more than one standard header are defined here. Standard headers
+ * then use:
+ * #ifdef _BSD_SIZE_T_
+ * typedef _BSD_SIZE_T_ size_t;
+ * #undef _BSD_SIZE_T_
+ * #endif
+ */
+#define _BSD_CLOCK_T_ unsigned long /* clock() */
+#define _BSD_SSIZE_T_ int /* byte count or error */
+#define _BSD_TIME_T_ __int64_t /* time() */
+#if __GNUC_PREREQ__(2, 96)
+#define _BSD_VA_LIST_ __builtin_va_list /* GCC built-in type */
+#else
+#define _BSD_VA_LIST_ char * /* va_list */
+#endif
+#define _BSD_CLOCKID_T_ int /* clockid_t */
+#define _BSD_TIMER_T_ int /* timer_t */
+#define _BSD_SUSECONDS_T_ int /* suseconds_t */
+#define _BSD_USECONDS_T_ unsigned int /* useconds_t */
+#define _BSD_WCHAR_T_ int /* wchar_t */
+#define _BSD_WINT_T_ int /* wint_t */
+#define _BSD_WCTRANS_T_ void * /* wctrans_t */
+#define _BSD_WCTYPE_T_ void * /* wctype_t */
+
+/*
+ * mbstate_t is an opaque object to keep conversion state, during multibyte
+ * stream conversions. The content must not be referenced by user programs.
+ */
+typedef union {
+ __int64_t __mbstateL; /* for alignment */
+ char __mbstate8[128];
+} __mbstate_t;
+#define _BSD_MBSTATE_T_ __mbstate_t /* mbstate_t */
+
+#endif /* _I386_ANSI_H_ */
diff --git a/libbsd/include/arch/i386/machine/asm.h b/libbsd/include/arch/i386/machine/asm.h
new file mode 100644
index 0000000..faefb38
--- /dev/null
+++ b/libbsd/include/arch/i386/machine/asm.h
@@ -0,0 +1,220 @@
+/* $NetBSD: asm.h,v 1.38 2008/05/03 05:54:52 yamt Exp $ */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)asm.h 5.5 (Berkeley) 5/7/91
+ */
+
+#ifndef _I386_ASM_H_
+#define _I386_ASM_H_
+
+#ifdef _KERNEL_OPT
+#include "opt_multiprocessor.h"
+#endif
+
+#ifdef PIC
+#define PIC_PROLOGUE \
+ pushl %ebx; \
+ call 1f; \
+1: \
+ popl %ebx; \
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+#define PIC_EPILOGUE \
+ popl %ebx
+#define PIC_PLT(x) x@PLT
+#define PIC_GOT(x) x@GOT(%ebx)
+#define PIC_GOTOFF(x) x@GOTOFF(%ebx)
+#else
+#define PIC_PROLOGUE
+#define PIC_EPILOGUE
+#define PIC_PLT(x) x
+#define PIC_GOT(x) x
+#define PIC_GOTOFF(x) x
+#endif
+
+#ifdef __ELF__
+# define _C_LABEL(x) x
+#else
+# ifdef __STDC__
+# define _C_LABEL(x) _ ## x
+# else
+# define _C_LABEL(x) _/**/x
+# endif
+#endif
+#define _ASM_LABEL(x) x
+
+#define CVAROFF(x, y) _C_LABEL(x) + y
+
+#ifdef __STDC__
+# define __CONCAT(x,y) x ## y
+# define __STRING(x) #x
+#else
+# define __CONCAT(x,y) x/**/y
+# define __STRING(x) "x"
+#endif
+
+/* let kernels and others override entrypoint alignment */
+#if !defined(_ALIGN_TEXT) && !defined(_KERNEL)
+# ifdef _STANDALONE
+# define _ALIGN_TEXT .align 4
+# elif defined __ELF__
+# define _ALIGN_TEXT .align 16
+# else
+# define _ALIGN_TEXT .align 4
+# endif
+#endif
+
+#define _ENTRY(x) \
+ .text; _ALIGN_TEXT; .globl x; .type x,@function; x:
+#define _LABEL(x) \
+ .globl x; x:
+
+#ifdef _KERNEL
+
+#define CPUVAR(off) %fs:__CONCAT(CPU_INFO_,off)
+
+/* XXX Can't use __CONCAT() here, as it would be evaluated incorrectly. */
+#ifdef __ELF__
+#ifdef __STDC__
+#define IDTVEC(name) \
+ ALIGN_TEXT; .globl X ## name; .type X ## name,@function; X ## name:
+#define IDTVEC_END(name) \
+ .size X ## name, . - X ## name
+#else
+#define IDTVEC(name) \
+ ALIGN_TEXT; .globl X/**/name; .type X/**/name,@function; X/**/name:
+#define IDTVEC_END(name) \
+ .size X/**/name, . - X/**/name
+#endif /* __STDC__ */
+#else
+#ifdef __STDC__
+#define IDTVEC(name) \
+ ALIGN_TEXT; .globl _X ## name; .type _X ## name,@function; _X ## name:
+#define IDTVEC_END(name) \
+ .size _X ## name, . - _X ## name
+#else
+#define IDTVEC(name) \
+ ALIGN_TEXT; .globl _X/**/name; .type _X/**/name,@function; _X/**/name:
+#define IDTVEC_END(name) \
+ .size _X/**/name, . - _X/**/name
+#endif /* __STDC__ */
+#endif /* __ELF__ */
+
+#ifdef _STANDALONE
+#define ALIGN_DATA .align 4
+#define ALIGN_TEXT .align 4 /* 4-byte boundaries */
+#define SUPERALIGN_TEXT .align 16 /* 15-byte boundaries */
+#elif defined __ELF__
+#define ALIGN_DATA .align 4
+#define ALIGN_TEXT .align 16 /* 16-byte boundaries */
+#define SUPERALIGN_TEXT .align 16 /* 16-byte boundaries */
+#else
+#define ALIGN_DATA .align 2
+#define ALIGN_TEXT .align 4 /* 16-byte boundaries */
+#define SUPERALIGN_TEXT .align 4 /* 16-byte boundaries */
+#endif /* __ELF__ */
+
+#define _ALIGN_TEXT ALIGN_TEXT
+
+#ifdef GPROF
+#ifdef __ELF__
+#define MCOUNT_ASM call _C_LABEL(__mcount)
+#else /* __ELF__ */
+#define MCOUNT_ASM call _C_LABEL(mcount)
+#endif /* __ELF__ */
+#else /* GPROF */
+#define MCOUNT_ASM /* nothing */
+#endif /* GPROF */
+
+#endif /* _KERNEL */
+
+
+
+#ifdef GPROF
+# ifdef __ELF__
+# define _PROF_PROLOGUE \
+ pushl %ebp; movl %esp,%ebp; call PIC_PLT(__mcount); popl %ebp
+# else
+# define _PROF_PROLOGUE \
+ pushl %ebp; movl %esp,%ebp; call PIC_PLT(mcount); popl %ebp
+# endif
+#else
+# define _PROF_PROLOGUE
+#endif
+
+#define ENTRY(y) _ENTRY(_C_LABEL(y)); _PROF_PROLOGUE
+#define NENTRY(y) _ENTRY(_C_LABEL(y))
+#define ASENTRY(y) _ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
+#define LABEL(y) _LABEL(_C_LABEL(y))
+#define END(y) .size y, . - y
+
+#define ASMSTR .asciz
+
+#ifdef __ELF__
+#define RCSID(x) .pushsection ".ident"; .asciz x; .popsection
+#else
+#define RCSID(x) .text; .asciz x
+#endif
+
+#ifdef NO_KERNEL_RCSIDS
+#define __KERNEL_RCSID(_n, _s) /* nothing */
+#else
+#define __KERNEL_RCSID(_n, _s) RCSID(_s)
+#endif
+
+#ifdef __ELF__
+#define WEAK_ALIAS(alias,sym) \
+ .weak alias; \
+ alias = sym
+#endif
+/*
+ * STRONG_ALIAS: create a strong alias.
+ */
+#define STRONG_ALIAS(alias,sym) \
+ .globl alias; \
+ alias = sym
+
+#ifdef __STDC__
+#define WARN_REFERENCES(sym,msg) \
+ .stabs msg ## ,30,0,0,0 ; \
+ .stabs __STRING(_C_LABEL(sym)) ## ,1,0,0,0
+#elif defined(__ELF__)
+#define WARN_REFERENCES(sym,msg) \
+ .stabs msg,30,0,0,0 ; \
+ .stabs __STRING(sym),1,0,0,0
+#else
+#define WARN_REFERENCES(sym,msg) \
+ .stabs msg,30,0,0,0 ; \
+ .stabs __STRING(_/**/sym),1,0,0,0
+#endif /* __STDC__ */
+
+#endif /* !_I386_ASM_H_ */
diff --git a/libbsd/include/arch/i386/machine/cdefs.h b/libbsd/include/arch/i386/machine/cdefs.h
new file mode 100644
index 0000000..0541bd7
--- /dev/null
+++ b/libbsd/include/arch/i386/machine/cdefs.h
@@ -0,0 +1,8 @@
+/* $NetBSD: cdefs.h,v 1.7 2008/10/26 06:57:30 mrg Exp $ */
+
+#ifndef _I386_CDEFS_H_
+#define _I386_CDEFS_H_
+
+/* No arch-specific cdefs. */
+
+#endif /* !_I386_CDEFS_H_ */
diff --git a/libbsd/include/arch/i386/machine/elf_machdep.h b/libbsd/include/arch/i386/machine/elf_machdep.h
new file mode 100644
index 0000000..442c561
--- /dev/null
+++ b/libbsd/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/libbsd/include/arch/i386/machine/int_types.h b/libbsd/include/arch/i386/machine/int_types.h
new file mode 100644
index 0000000..69c661c
--- /dev/null
+++ b/libbsd/include/arch/i386/machine/int_types.h
@@ -0,0 +1,66 @@
+/* $NetBSD: int_types.h,v 1.10 2005/12/24 20:07:10 perry Exp $ */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * from: @(#)types.h 7.5 (Berkeley) 3/9/91
+ */
+
+#ifndef _I386_INT_TYPES_H_
+#define _I386_INT_TYPES_H_
+
+#include <sys/cdefs.h>
+
+/*
+ * 7.18.1 Integer types
+ */
+
+/* 7.18.1.1 Exact-width integer types */
+
+typedef signed char __int8_t;
+typedef unsigned char __uint8_t;
+typedef short int __int16_t;
+typedef unsigned short int __uint16_t;
+#ifdef __COMPILER_INT64__
+typedef __COMPILER_INT64__ __int64_t;
+typedef __COMPILER_UINT64__ __uint64_t;
+#else
+/* LONGLONG */
+typedef long long int __int64_t;
+/* LONGLONG */
+typedef unsigned long long int __uint64_t;
+#endif
+
+#define __BIT_TYPES_DEFINED__
+
+/* 7.18.1.4 Integer types capable of holding object pointers */
+
+typedef int __intptr_t;
+typedef unsigned int __uintptr_t;
+
+#endif /* !_I386_INT_TYPES_H_ */
diff --git a/libbsd/include/arch/m68k/machine/ansi.h b/libbsd/include/arch/m68k/machine/ansi.h
new file mode 100644
index 0000000..a6e1f6c
--- /dev/null
+++ b/libbsd/include/arch/m68k/machine/ansi.h
@@ -0,0 +1,104 @@
+/* $NetBSD: ansi.h,v 1.16 2005/04/14 20:06:15 matt Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)ansi.h 8.2 (Berkeley) 1/4/94
+ */
+
+#ifndef _ANSI_H_
+#define _ANSI_H_
+
+#include <sys/cdefs.h>
+#include <machine/int_types.h>
+
+/*
+ * Types which are fundamental to the implementation and may appear in
+ * more than one standard header are defined here. Standard headers
+ * then use:
+ * #ifdef _BSD_SIZE_T_
+ * typedef _BSD_SIZE_T_ size_t;
+ * #undef _BSD_SIZE_T_
+ * #endif
+ */
+#define _BSD_CLOCK_T_ unsigned long /* clock() */
+#ifndef _BSD_PTRDIFF_T_
+#define _BSD_PTRDIFF_T_ int /* ptr1 - ptr2 */
+#endif
+#ifdef _BSD_SIZE_T_
+#undef _BSD_SIZE_T_
+#define _BSD_SIZE_T_ size_t
+#else
+#define _BSD_SIZE_T_ unsigned int /* sizeof() */
+#endif
+#define _BSD_SSIZE_T_ int /* byte count or error */
+#define _BSD_TIME_T_ long /* time() */
+#if __GNUC_PREREQ__(3,0)
+#define _BSD_VA_LIST_ __builtin_va_list /* va_list */
+#else
+#define _BSD_VA_LIST_ char * /* va_list */
+#endif
+#define _BSD_CLOCKID_T_ int /* clockid_t */
+#define _BSD_TIMER_T_ int /* timer_t */
+#define _BSD_SUSECONDS_T_ int /* suseconds_t */
+#define _BSD_USECONDS_T_ unsigned int /* useconds_t */
+
+/*
+ * NOTE: rune_t is not covered by ANSI nor other standards, and should not
+ * be instantiated outside of lib/libc/locale. use wchar_t.
+ *
+ * Runes (wchar_t) is declared to be an ``int'' instead of the more natural
+ * ``unsigned long'' or ``long''. Two things are happening here. It is not
+ * unsigned so that EOF (-1) can be naturally assigned to it and used. Also,
+ * it looks like 10646 will be a 31 bit standard. This means that if your
+ * ints cannot hold 32 bits, you will be in trouble. The reason an int was
+ * chosen over a long is that the is*() and to*() routines take ints (says
+ * ANSI C), but they use _RUNE_T_ instead of int. By changing it here, you
+ * lose a bit of ANSI conformance, but your programs will still work.
+ *
+ * Note that _WCHAR_T_ and _RUNE_T_ must be of the same type. When wchar_t
+ * and rune_t are typedef'd, _WCHAR_T_ will be undef'd, but _RUNE_T remains
+ * defined for ctype.h.
+ */
+#define _BSD_WCHAR_T_ int /* wchar_t */
+#define _BSD_WINT_T_ int /* wint_t */
+#define _BSD_RUNE_T_ int /* rune_t */
+#define _BSD_WCTRANS_T_ void * /* wctrans_t */
+#define _BSD_WCTYPE_T_ void * /* wctype_t */
+
+/*
+ * mbstate_t is an opaque object to keep conversion state, during multibyte
+ * stream conversions. The content must not be referenced by user programs.
+ */
+typedef union {
+ char __mbstate8[128];
+ __int64_t __mbstateL; /* for alignment */
+} __mbstate_t;
+#define _BSD_MBSTATE_T_ __mbstate_t /* mbstate_t */
+
+#endif /* _ANSI_H_ */
diff --git a/libbsd/include/arch/m68k/machine/asm.h b/libbsd/include/arch/m68k/machine/asm.h
new file mode 100644
index 0000000..ec932b9
--- /dev/null
+++ b/libbsd/include/arch/m68k/machine/asm.h
@@ -0,0 +1,232 @@
+/* $NetBSD: asm.h,v 1.25 2008/04/28 20:23:26 martin Exp $ */
+
+/*-
+ * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * 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.
+ */
+
+/*
+ * Copyright (c) 1994 Allen Briggs
+ * All rights reserved.
+ *
+ * Gleaned from locore.s and sun3 asm.h which had the following copyrights:
+ * locore.s:
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 1990 The Regents of the University of California.
+ * sun3/include/asm.h:
+ * Copyright (c) 1993 Adam Glass
+ * Copyright (c) 1990 The Regents of the University of California.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 _M68K_ASM_H_
+#define _M68K_ASM_H_
+
+#if defined(__ELF__) && defined(PIC)
+#define PIC_PLT(name) name@PLTPC
+#else
+#define PIC_PLT(name) name
+#endif
+
+#ifdef __ELF__
+# if __STDC__
+# define _C_LABEL(name) name
+# else
+# define _C_LABEL(name) name
+#endif /* __STDC__ */
+#else /* __ELF__ */
+# if __STDC__
+# define _C_LABEL(name) _ ## name
+# else
+# define _C_LABEL(name) _/**/name
+# endif /* __STDC__ */
+#endif /* __ELF__ */
+
+#define _ASM_LABEL(name) name
+
+#define _ENTRY(name) \
+ .text; .even; .globl name; .type name,@function; name:
+
+#ifdef __ELF__
+#define MCOUNT_ENTRY __mcount
+#else
+#define MCOUNT_ENTRY mcount
+#endif
+
+#ifdef GPROF
+#define _PROF_PROLOG link %a6,#0; jbsr MCOUNT_ENTRY; unlk %a6
+#else
+#define _PROF_PROLOG
+#endif
+
+#define ENTRY(name) _ENTRY(_C_LABEL(name)) _PROF_PROLOG
+#define ASENTRY(name) _ENTRY(_ASM_LABEL(name)) _PROF_PROLOG
+
+#define ENTRY_NOPROFILE(name) _ENTRY(_C_LABEL(name))
+#define ASENTRY_NOPROFILE(name) _ENTRY(_ASM_LABEL(name))
+
+/*
+ * The m68k ALTENTRY macro is very different than the traditional
+ * implementation used by other NetBSD ports. Usually ALTENTRY
+ * simply provides an alternate function entry point. The m68k
+ * definition takes a second argument and jumps inside the second
+ * function when profiling is enabled.
+ *
+ * The m68k behavior is similar to the ENTRY2 macro found in
+ * solaris' asm_linkage.h.
+ *
+ * Providing ENTRY2 and changing all the code that uses ALTENTRY
+ * to use it would be a desirable change.
+ */
+#ifdef PROF
+#define ALTENTRY(name, rname) ENTRY(name); jra rname+12
+#else
+#define ALTENTRY(name, rname) _ENTRY(_C_LABEL(name))
+#endif
+
+#define RCSID(x) .text ; \
+ .asciz x ; \
+ .even
+
+/*
+ * Global variables of whatever sort.
+ */
+#define GLOBAL(x) \
+ .globl _C_LABEL(x) ; \
+ _C_LABEL(x):
+
+#define ASGLOBAL(x) \
+ .globl _ASM_LABEL(x) ; \
+ _ASM_LABEL(x):
+
+/*
+ * ...and local variables.
+ */
+#define LOCAL(x) \
+ _C_LABEL(x):
+
+#define ASLOCAL(x) \
+ _ASM_LABEL(x):
+
+/*
+ * Items in the BSS segment.
+ */
+#define BSS(name, size) \
+ .comm _C_LABEL(name),size
+
+#define ASBSS(name, size) \
+ .comm _ASM_LABEL(name),size
+
+#ifdef _KERNEL
+/*
+ * Shorthand for calling panic().
+ * Note the side-effect: it uses up the 9: label, so be careful!
+ */
+#define PANIC(x) \
+ pea 9f ; \
+ jbsr _C_LABEL(panic) ; \
+ 9: .asciz x ; \
+ .even
+
+#endif /* _KERNEL */
+
+/*
+ * Shorthand for defining vectors for the vector table.
+ */
+#define VECTOR(x) \
+ .long _C_LABEL(x)
+
+#define ASVECTOR(x) \
+ .long _ASM_LABEL(x)
+
+#define VECTOR_UNUSED \
+ .long 0
+
+#ifdef __ELF__
+#define WEAK_ALIAS(alias,sym) \
+ .weak alias; \
+ alias = sym
+#endif
+/*
+ * STRONG_ALIAS: create a strong alias.
+ */
+#define STRONG_ALIAS(alias,sym) \
+ .globl alias; \
+ alias = sym
+
+#ifdef __STDC__
+#define __STRING(x) #x
+#define WARN_REFERENCES(sym,msg) \
+ .stabs msg ## ,30,0,0,0 ; \
+ .stabs __STRING(_ ## sym) ## ,1,0,0,0
+#else
+#define __STRING(x) "x"
+#define WARN_REFERENCES(sym,msg) \
+ .stabs msg,30,0,0,0 ; \
+ .stabs __STRING(_/**/sym),1,0,0,0
+#endif /* __STDC__ */
+
+/*
+ * Macros to hide shortcomings in the 68010.
+ */
+#ifndef __mc68010__
+#define EXTBL(reg) \
+ extbl reg
+#else /* __mc68010__ */
+#define EXTBL(reg) \
+ extw reg ; \
+ extl reg
+#endif /* __mc68010__ */
+
+#endif /* _M68K_ASM_H_ */
diff --git a/libbsd/include/arch/m68k/machine/cdefs.h b/libbsd/include/arch/m68k/machine/cdefs.h
new file mode 100644
index 0000000..00b74e9
--- /dev/null
+++ b/libbsd/include/arch/m68k/machine/cdefs.h
@@ -0,0 +1,8 @@
+/* $NetBSD: cdefs.h,v 1.6 1999/03/20 01:40:26 thorpej Exp $ */
+
+#ifndef _M68K_CDEFS_H_
+#define _M68K_CDEFS_H_
+
+/* No arch-specific cdefs. */
+
+#endif /* !_M68K_CDEFS_H_ */
diff --git a/libbsd/include/arch/m68k/machine/elf_machdep.h b/libbsd/include/arch/m68k/machine/elf_machdep.h
new file mode 100644
index 0000000..9a987c6
--- /dev/null
+++ b/libbsd/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/libbsd/include/arch/m68k/machine/int_types.h b/libbsd/include/arch/m68k/machine/int_types.h
new file mode 100644
index 0000000..5940785
--- /dev/null
+++ b/libbsd/include/arch/m68k/machine/int_types.h
@@ -0,0 +1,70 @@
+/* $NetBSD: int_types.h,v 1.7 2005/09/06 19:18:23 kleink Exp $ */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * from: @(#)types.h 7.9 (Berkeley) 3/9/91
+ */
+
+#ifndef _M68K_INT_TYPES_H_
+#define _M68K_INT_TYPES_H_
+
+#include <sys/cdefs.h>
+
+#ifndef __rtems__
+/*
+ * 7.18.1 Integer types
+ */
+
+/* 7.18.1.1 Exact-width integer types */
+
+typedef __signed char __int8_t;
+typedef unsigned char __uint8_t;
+typedef short int __int16_t;
+typedef unsigned short int __uint16_t;
+typedef int __int32_t;
+typedef unsigned int __uint32_t;
+#endif
+#ifdef __COMPILER_INT64__
+typedef __COMPILER_INT64__ __int64_t;
+typedef __COMPILER_UINT64__ __uint64_t;
+#else
+/* LONGLONG */
+typedef long long int __int64_t;
+/* LONGLONG */
+typedef unsigned long long int __uint64_t;
+#endif
+
+#define __BIT_TYPES_DEFINED__
+
+/* 7.18.1.4 Integer types capable of holding object pointers */
+
+typedef int __intptr_t;
+typedef unsigned int __uintptr_t;
+
+#endif /* !_M68K_INT_TYPES_H_ */
diff --git a/libbsd/include/arch/nios2/machine/ansi.h b/libbsd/include/arch/nios2/machine/ansi.h
new file mode 100644
index 0000000..a6e1f6c
--- /dev/null
+++ b/libbsd/include/arch/nios2/machine/ansi.h
@@ -0,0 +1,104 @@
+/* $NetBSD: ansi.h,v 1.16 2005/04/14 20:06:15 matt Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)ansi.h 8.2 (Berkeley) 1/4/94
+ */
+
+#ifndef _ANSI_H_
+#define _ANSI_H_
+
+#include <sys/cdefs.h>
+#include <machine/int_types.h>
+
+/*
+ * Types which are fundamental to the implementation and may appear in
+ * more than one standard header are defined here. Standard headers
+ * then use:
+ * #ifdef _BSD_SIZE_T_
+ * typedef _BSD_SIZE_T_ size_t;
+ * #undef _BSD_SIZE_T_
+ * #endif
+ */
+#define _BSD_CLOCK_T_ unsigned long /* clock() */
+#ifndef _BSD_PTRDIFF_T_
+#define _BSD_PTRDIFF_T_ int /* ptr1 - ptr2 */
+#endif
+#ifdef _BSD_SIZE_T_
+#undef _BSD_SIZE_T_
+#define _BSD_SIZE_T_ size_t
+#else
+#define _BSD_SIZE_T_ unsigned int /* sizeof() */
+#endif
+#define _BSD_SSIZE_T_ int /* byte count or error */
+#define _BSD_TIME_T_ long /* time() */
+#if __GNUC_PREREQ__(3,0)
+#define _BSD_VA_LIST_ __builtin_va_list /* va_list */
+#else
+#define _BSD_VA_LIST_ char * /* va_list */
+#endif
+#define _BSD_CLOCKID_T_ int /* clockid_t */
+#define _BSD_TIMER_T_ int /* timer_t */
+#define _BSD_SUSECONDS_T_ int /* suseconds_t */
+#define _BSD_USECONDS_T_ unsigned int /* useconds_t */
+
+/*
+ * NOTE: rune_t is not covered by ANSI nor other standards, and should not
+ * be instantiated outside of lib/libc/locale. use wchar_t.
+ *
+ * Runes (wchar_t) is declared to be an ``int'' instead of the more natural
+ * ``unsigned long'' or ``long''. Two things are happening here. It is not
+ * unsigned so that EOF (-1) can be naturally assigned to it and used. Also,
+ * it looks like 10646 will be a 31 bit standard. This means that if your
+ * ints cannot hold 32 bits, you will be in trouble. The reason an int was
+ * chosen over a long is that the is*() and to*() routines take ints (says
+ * ANSI C), but they use _RUNE_T_ instead of int. By changing it here, you
+ * lose a bit of ANSI conformance, but your programs will still work.
+ *
+ * Note that _WCHAR_T_ and _RUNE_T_ must be of the same type. When wchar_t
+ * and rune_t are typedef'd, _WCHAR_T_ will be undef'd, but _RUNE_T remains
+ * defined for ctype.h.
+ */
+#define _BSD_WCHAR_T_ int /* wchar_t */
+#define _BSD_WINT_T_ int /* wint_t */
+#define _BSD_RUNE_T_ int /* rune_t */
+#define _BSD_WCTRANS_T_ void * /* wctrans_t */
+#define _BSD_WCTYPE_T_ void * /* wctype_t */
+
+/*
+ * mbstate_t is an opaque object to keep conversion state, during multibyte
+ * stream conversions. The content must not be referenced by user programs.
+ */
+typedef union {
+ char __mbstate8[128];
+ __int64_t __mbstateL; /* for alignment */
+} __mbstate_t;
+#define _BSD_MBSTATE_T_ __mbstate_t /* mbstate_t */
+
+#endif /* _ANSI_H_ */
diff --git a/libbsd/include/arch/nios2/machine/asm.h b/libbsd/include/arch/nios2/machine/asm.h
new file mode 100644
index 0000000..04a1973
--- /dev/null
+++ b/libbsd/include/arch/nios2/machine/asm.h
@@ -0,0 +1,219 @@
+/* $NetBSD: asm.h,v 1.25 2008/04/28 20:23:26 martin Exp $ */
+
+/*-
+ * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * 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.
+ */
+
+/*
+ * Copyright (c) 1994 Allen Briggs
+ * All rights reserved.
+ *
+ * Gleaned from locore.s and sun3 asm.h which had the following copyrights:
+ * locore.s:
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 1990 The Regents of the University of California.
+ * sun3/include/asm.h:
+ * Copyright (c) 1993 Adam Glass
+ * Copyright (c) 1990 The Regents of the University of California.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 _NIOS2_ASM_H_
+#define _NIOS2_ASM_H_
+
+#if defined(__ELF__) && defined(PIC)
+#define PIC_PLT(name) name@PLTPC
+#else
+#define PIC_PLT(name) name
+#endif
+
+#ifdef __ELF__
+# if __STDC__
+# define _C_LABEL(name) name
+# else
+# define _C_LABEL(name) name
+#endif /* __STDC__ */
+#else /* __ELF__ */
+# if __STDC__
+# define _C_LABEL(name) _ ## name
+# else
+# define _C_LABEL(name) _/**/name
+# endif /* __STDC__ */
+#endif /* __ELF__ */
+
+#define _ASM_LABEL(name) name
+
+#define _ENTRY(name) \
+ .text; .even; .globl name; .type name,@function; name:
+
+#ifdef __ELF__
+#define MCOUNT_ENTRY __mcount
+#else
+#define MCOUNT_ENTRY mcount
+#endif
+
+#ifdef GPROF
+#define _PROF_PROLOG xx
+#else
+#define _PROF_PROLOG
+#endif
+
+#define ENTRY(name) _ENTRY(_C_LABEL(name)) _PROF_PROLOG
+#define ASENTRY(name) _ENTRY(_ASM_LABEL(name)) _PROF_PROLOG
+
+#define ENTRY_NOPROFILE(name) _ENTRY(_C_LABEL(name))
+#define ASENTRY_NOPROFILE(name) _ENTRY(_ASM_LABEL(name))
+
+/*
+ * The m68k ALTENTRY macro is very different than the traditional
+ * implementation used by other NetBSD ports. Usually ALTENTRY
+ * simply provides an alternate function entry point. The m68k
+ * definition takes a second argument and jumps inside the second
+ * function when profiling is enabled.
+ *
+ * The m68k behavior is similar to the ENTRY2 macro found in
+ * solaris' asm_linkage.h.
+ *
+ * Providing ENTRY2 and changing all the code that uses ALTENTRY
+ * to use it would be a desirable change.
+ */
+#ifdef PROF
+#define ALTENTRY(name, rname) ENTRY(name); jmp rname+12
+#else
+#define ALTENTRY(name, rname) _ENTRY(_C_LABEL(name))
+#endif
+
+#define RCSID(x) .text ; \
+ .asciz x ; \
+ .even
+
+/*
+ * Global variables of whatever sort.
+ */
+#define GLOBAL(x) \
+ .globl _C_LABEL(x) ; \
+ _C_LABEL(x):
+
+#define ASGLOBAL(x) \
+ .globl _ASM_LABEL(x) ; \
+ _ASM_LABEL(x):
+
+/*
+ * ...and local variables.
+ */
+#define LOCAL(x) \
+ _C_LABEL(x):
+
+#define ASLOCAL(x) \
+ _ASM_LABEL(x):
+
+/*
+ * Items in the BSS segment.
+ */
+#define BSS(name, size) \
+ .comm _C_LABEL(name),size
+
+#define ASBSS(name, size) \
+ .comm _ASM_LABEL(name),size
+
+#ifdef _KERNEL
+/*
+ * Shorthand for calling panic().
+ * Note the side-effect: it uses up the 9: label, so be careful!
+ */
+#define PANIC(x) \
+ jmp _C_LABEL(panic) ; \
+ 9: .asciz x ; \
+ .even
+
+#endif /* _KERNEL */
+
+/*
+ * Shorthand for defining vectors for the vector table.
+ */
+#define VECTOR(x) \
+ .long _C_LABEL(x)
+
+#define ASVECTOR(x) \
+ .long _ASM_LABEL(x)
+
+#define VECTOR_UNUSED \
+ .long 0
+
+#ifdef __ELF__
+#define WEAK_ALIAS(alias,sym) \
+ .weak alias; \
+ alias = sym
+#endif
+/*
+ * STRONG_ALIAS: create a strong alias.
+ */
+#define STRONG_ALIAS(alias,sym) \
+ .globl alias; \
+ alias = sym
+
+#ifdef __STDC__
+#define __STRING(x) #x
+#define WARN_REFERENCES(sym,msg) \
+ .stabs msg ## ,30,0,0,0 ; \
+ .stabs __STRING(_ ## sym) ## ,1,0,0,0
+#else
+#define __STRING(x) "x"
+#define WARN_REFERENCES(sym,msg) \
+ .stabs msg,30,0,0,0 ; \
+ .stabs __STRING(_/**/sym),1,0,0,0
+#endif /* __STDC__ */
+
+#endif /* _NIOS2_ASM_H_ */
diff --git a/libbsd/include/arch/nios2/machine/cdefs.h b/libbsd/include/arch/nios2/machine/cdefs.h
new file mode 100644
index 0000000..f407a80
--- /dev/null
+++ b/libbsd/include/arch/nios2/machine/cdefs.h
@@ -0,0 +1,8 @@
+/* $NetBSD: cdefs.h,v 1.6 1999/03/20 01:40:26 thorpej Exp $ */
+
+#ifndef _NIOS2_CDEFS_H_
+#define _NIOS2_CDEFS_H_
+
+/* No arch-specific cdefs. */
+
+#endif /* !_NIOS2_CDEFS_H_ */
diff --git a/libbsd/include/arch/nios2/machine/elf_machdep.h b/libbsd/include/arch/nios2/machine/elf_machdep.h
new file mode 100644
index 0000000..3f3c108
--- /dev/null
+++ b/libbsd/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/libbsd/include/arch/nios2/machine/int_types.h b/libbsd/include/arch/nios2/machine/int_types.h
new file mode 100644
index 0000000..2a869d1
--- /dev/null
+++ b/libbsd/include/arch/nios2/machine/int_types.h
@@ -0,0 +1,70 @@
+/* $NetBSD: int_types.h,v 1.7 2005/09/06 19:18:23 kleink Exp $ */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * from: @(#)types.h 7.9 (Berkeley) 3/9/91
+ */
+
+#ifndef _NIOS2_INT_TYPES_H_
+#define _NIOS2_INT_TYPES_H_
+
+#include <sys/cdefs.h>
+
+#ifndef __rtems__
+/*
+ * 7.18.1 Integer types
+ */
+
+/* 7.18.1.1 Exact-width integer types */
+
+typedef __signed char __int8_t;
+typedef unsigned char __uint8_t;
+typedef short int __int16_t;
+typedef unsigned short int __uint16_t;
+typedef int __int32_t;
+typedef unsigned int __uint32_t;
+#endif
+#ifdef __COMPILER_INT64__
+typedef __COMPILER_INT64__ __int64_t;
+typedef __COMPILER_UINT64__ __uint64_t;
+#else
+/* LONGLONG */
+typedef long long int __int64_t;
+/* LONGLONG */
+typedef unsigned long long int __uint64_t;
+#endif
+
+#define __BIT_TYPES_DEFINED__
+
+/* 7.18.1.4 Integer types capable of holding object pointers */
+
+typedef int __intptr_t;
+typedef unsigned int __uintptr_t;
+
+#endif /* !_NIOS2_INT_TYPES_H_ */
diff --git a/libbsd/include/arch/sparc/machine/ansi.h b/libbsd/include/arch/sparc/machine/ansi.h
new file mode 100644
index 0000000..07a3ca5
--- /dev/null
+++ b/libbsd/include/arch/sparc/machine/ansi.h
@@ -0,0 +1,78 @@
+/* $NetBSD: ansi.h,v 1.21 2009/01/11 02:45:46 christos Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)ansi.h 8.2 (Berkeley) 1/4/94
+ */
+
+#ifndef _ANSI_H_
+#define _ANSI_H_
+
+#include <sys/cdefs.h>
+#include <machine/int_types.h>
+
+/*
+ * Types which are fundamental to the implementation and may appear in
+ * more than one standard header are defined here. Standard headers
+ * then use:
+ * #ifdef _BSD_SIZE_T_
+ * typedef _BSD_SIZE_T_ size_t;
+ * #undef _BSD_SIZE_T_
+ * #endif
+ */
+#define _BSD_CLOCK_T_ unsigned long /* clock() */
+#define _BSD_PTRDIFF_T_ long /* ptr1 - ptr2 */
+#define _BSD_SIZE_T_ unsigned long /* sizeof() */
+#define _BSD_SSIZE_T_ long /* byte count or error */
+#define _BSD_TIME_T_ __int64_t /* time() */
+#if __GNUC_PREREQ__(3, 0)
+#define _BSD_VA_LIST_ __builtin_va_list /* va_list */
+#else
+#define _BSD_VA_LIST_ char * /* va_list */
+#endif
+#define _BSD_CLOCKID_T_ int /* clockid_t */
+#define _BSD_TIMER_T_ int /* timer_t */
+#define _BSD_SUSECONDS_T_ int /* suseconds_t */
+#define _BSD_USECONDS_T_ unsigned int /* useconds_t */
+#define _BSD_WCHAR_T_ int /* wchar_t */
+#define _BSD_WINT_T_ int /* wint_t */
+#define _BSD_WCTRANS_T_ void * /* wctrans_t */
+#define _BSD_WCTYPE_T_ void * /* wctype_t */
+
+/*
+ * mbstate_t is an opaque object to keep conversion state, during multibyte
+ * stream conversions. The content must not be referenced by user programs.
+ */
+typedef union {
+ __int64_t __mbstateL; /* for alignment */
+ char __mbstate8[128];
+} __mbstate_t;
+#define _BSD_MBSTATE_T_ __mbstate_t /* mbstate_t */
+
+#endif /* _ANSI_H_ */
diff --git a/libbsd/include/arch/sparc/machine/asm.h b/libbsd/include/arch/sparc/machine/asm.h
new file mode 100644
index 0000000..3cacfbb
--- /dev/null
+++ b/libbsd/include/arch/sparc/machine/asm.h
@@ -0,0 +1,208 @@
+/* $NetBSD: asm.h,v 1.16 2006/01/20 22:02:40 christos Exp $ */
+
+/*
+ * Copyright (c) 1994 Allen Briggs
+ * All rights reserved.
+ *
+ * Gleaned from locore.s and sun3 asm.h which had the following copyrights:
+ * locore.s:
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 1990 The Regents of the University of California.
+ * sun3/include/asm.h:
+ * Copyright (c) 1993 Adam Glass
+ * Copyright (c) 1990 The Regents of the University of California.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 _ASM_H_
+#define _ASM_H_
+
+/* Pull in CCFSZ, CC64FSZ, and BIAS from frame.h */
+#ifndef _LOCORE
+#define _LOCORE
+#endif
+#include <machine/frame.h>
+
+#ifdef __ELF__
+#define _C_LABEL(name) name
+#else
+#ifdef __STDC__
+#define _C_LABEL(name) _ ## name
+#else
+#define _C_LABEL(name) _/**/name
+#endif
+#endif
+#define _ASM_LABEL(name) name
+
+#ifdef PIC
+/*
+ * PIC_PROLOGUE() is akin to the compiler generated function prologue for
+ * PIC code. It leaves the address of the Global Offset Table in DEST,
+ * clobbering register TMP in the process.
+ *
+ * We can use two code sequences. We can read the %pc or use the call
+ * instruction that saves the pc in %o7. Call requires the branch unit and
+ * IEU1, and clobbers %o7 which needs to be restored. This instruction
+ * sequence takes about 4 cycles due to instruction interdependence. Reading
+ * the pc takes 4 cycles to dispatch and is always dispatched alone. That
+ * sequence takes 7 cycles.
+ */
+#ifdef __arch64__
+#define PIC_PROLOGUE(dest,tmp) \
+ mov %o7, tmp; \
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-4),dest; \
+ call 0f; \
+ or dest,%lo(_GLOBAL_OFFSET_TABLE_+4),dest; \
+0: \
+ add dest,%o7,dest; \
+ mov tmp, %o7
+#else
+#define PIC_PROLOGUE(dest,tmp) \
+ mov %o7,tmp; 3: call 4f; nop; 4: \
+ sethi %hi(_C_LABEL(_GLOBAL_OFFSET_TABLE_)-(3b-.)),dest; \
+ or dest,%lo(_C_LABEL(_GLOBAL_OFFSET_TABLE_)-(3b-.)),dest; \
+ add dest,%o7,dest; mov tmp,%o7
+#endif
+
+/*
+ * PICCY_SET() does the equivalent of a `set var, %dest' instruction in
+ * a PIC-like way, but without involving the Global Offset Table. This
+ * only works for VARs defined in the same file *and* in the text segment.
+ */
+#ifdef __arch64__
+#define PICCY_SET(var,dest,tmp) \
+ 3: rd %pc, tmp; add tmp,(var-3b),dest
+#else
+#define PICCY_SET(var,dest,tmp) \
+ mov %o7,tmp; 3: call 4f; nop; 4: \
+ add %o7,(var-3b),dest; mov tmp,%o7
+#endif
+#else
+#define PIC_PROLOGUE(dest,tmp)
+#define PICCY_OFFSET(var,dest,tmp)
+#endif
+
+#define FTYPE(x) .type x,@function
+#define OTYPE(x) .type x,@object
+
+#define _ENTRY(name) \
+ .align 4; .globl name; .proc 1; FTYPE(name); name:
+
+#ifdef GPROF
+/* see _MCOUNT_ENTRY in profile.h */
+#ifdef __ELF__
+#ifdef __arch64__
+#define _PROF_PROLOGUE \
+ .data; .align 8; 1: .uaword 0; .uaword 0; \
+ .text; save %sp,-CC64FSZ,%sp; sethi %hi(1b),%o0; call _mcount; \
+ or %o0,%lo(1b),%o0; restore
+#else
+#define _PROF_PROLOGUE \
+ .data; .align 4; 1: .long 0; \
+ .text; save %sp,-96,%sp; sethi %hi(1b),%o0; call _mcount; \
+ or %o0,%lo(1b),%o0; restore
+#endif
+#else
+#ifdef __arch64__
+#define _PROF_PROLOGUE \
+ .data; .align 8; 1: .uaword 0; .uaword 0; \
+ .text; save %sp,-CC64FSZ,%sp; sethi %hi(1b),%o0; call mcount; \
+ or %o0,%lo(1b),%o0; restore
+#else
+#define _PROF_PROLOGUE \
+ .data; .align 4; 1: .long 0; \
+ .text; save %sp,-96,%sp; sethi %hi(1b),%o0; call mcount; \
+ or %o0,%lo(1b),%o0; restore
+#endif
+#endif
+#else
+#define _PROF_PROLOGUE
+#endif
+
+#define ENTRY(name) _ENTRY(_C_LABEL(name)); _PROF_PROLOGUE
+#define ENTRY_NOPROFILE(name) _ENTRY(_C_LABEL(name))
+#define ASENTRY(name) _ENTRY(_ASM_LABEL(name)); _PROF_PROLOGUE
+#define FUNC(name) ASENTRY(name)
+#define RODATA(name) .align 4; .text; .globl _C_LABEL(name); \
+ OTYPE(_C_LABEL(name)); _C_LABEL(name):
+
+
+#define ASMSTR .asciz
+
+#ifdef __ELF__
+#define RCSID(name) .pushsection ".ident"; .asciz name; .popsection
+#else
+#define RCSID(name) .asciz name
+#endif
+
+#ifdef NO_KERNEL_RCSIDS
+#define __KERNEL_RCSID(_n, _s) /* nothing */
+#else
+#define __KERNEL_RCSID(_n, _s) RCSID(_s)
+#endif
+
+#ifdef __ELF__
+#define WEAK_ALIAS(alias,sym) \
+ .weak alias; \
+ alias = sym
+#endif
+/*
+ * STRONG_ALIAS: create a strong alias.
+ */
+#define STRONG_ALIAS(alias,sym) \
+ .globl alias; \
+ alias = sym
+
+/*
+ * WARN_REFERENCES: create a warning if the specified symbol is referenced.
+ */
+#ifdef __ELF__
+#ifdef __STDC__
+#define WARN_REFERENCES(_sym,_msg) \
+ .section .gnu.warning. ## _sym ; .ascii _msg ; .text
+#else
+#define WARN_REFERENCES(_sym,_msg) \
+ .section .gnu.warning./**/_sym ; .ascii _msg ; .text
+#endif /* __STDC__ */
+#else
+#ifdef __STDC__
+#define __STRING(x) #x
+#define WARN_REFERENCES(sym,msg) \
+ .stabs msg ## ,30,0,0,0 ; \
+ .stabs __STRING(_ ## sym) ## ,1,0,0,0
+#else
+#define __STRING(x) "x"
+#define WARN_REFERENCES(sym,msg) \
+ .stabs msg,30,0,0,0 ; \
+ .stabs __STRING(_/**/sym),1,0,0,0
+#endif /* __STDC__ */
+#endif /* __ELF__ */
+
+#endif /* _ASM_H_ */
diff --git a/libbsd/include/arch/sparc/machine/cdefs.h b/libbsd/include/arch/sparc/machine/cdefs.h
new file mode 100644
index 0000000..93b436f
--- /dev/null
+++ b/libbsd/include/arch/sparc/machine/cdefs.h
@@ -0,0 +1,8 @@
+/* $NetBSD: cdefs.h,v 1.11 2005/12/11 12:19:05 christos Exp $ */
+
+#ifndef _MACHINE_CDEFS_H_
+#define _MACHINE_CDEFS_H_
+
+/* No arch-specific cdefs. */
+
+#endif /* !_MACHINE_CDEFS_H_ */
diff --git a/libbsd/include/arch/sparc/machine/elf_machdep.h b/libbsd/include/arch/sparc/machine/elf_machdep.h
new file mode 100644
index 0000000..e8f2b63
--- /dev/null
+++ b/libbsd/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/libbsd/include/arch/sparc/machine/int_types.h b/libbsd/include/arch/sparc/machine/int_types.h
new file mode 100644
index 0000000..c875844
--- /dev/null
+++ b/libbsd/include/arch/sparc/machine/int_types.h
@@ -0,0 +1,85 @@
+/* $NetBSD: int_types.h,v 1.10 2005/12/24 20:07:32 perry Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * from: @(#)types.h 8.1 (Berkeley) 6/11/93
+ */
+
+#ifndef _SPARC_INT_TYPES_H_
+#define _SPARC_INT_TYPES_H_
+
+#include <sys/cdefs.h>
+
+/*
+ * 7.18.1 Integer types
+ */
+
+/* 7.18.1.1 Exact-width integer types */
+
+typedef signed char __int8_t;
+typedef unsigned char __uint8_t;
+typedef short int __int16_t;
+typedef unsigned short int __uint16_t;
+typedef int __int32_t;
+typedef unsigned int __uint32_t;
+
+#ifdef __COMPILER_INT64__
+typedef __COMPILER_INT64__ __int64_t;
+typedef __COMPILER_UINT64__ __uint64_t;
+#else
+#ifdef __arch64__
+/* 64-bit compiler */
+typedef long int __int64_t;
+typedef unsigned long int __uint64_t;
+#else
+/* 32-bit compiler */
+/* LONGLONG */
+typedef long long int __int64_t;
+/* LONGLONG */
+typedef unsigned long long int __uint64_t;
+#endif
+#endif /* !__COMPILER_INT64__ */
+
+#define __BIT_TYPES_DEFINED__
+
+/* 7.18.1.4 Integer types capable of holding object pointers */
+
+typedef long int __intptr_t;
+typedef unsigned long int __uintptr_t;
+
+#endif /* !_SPARC_INT_TYPES_H_ */
diff --git a/libbsd/include/dlfcn.h b/libbsd/include/dlfcn.h
new file mode 100644
index 0000000..f1faf45
--- /dev/null
+++ b/libbsd/include/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 *);
+__aconst 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/libbsd/include/err.h b/libbsd/include/err.h
new file mode 100644
index 0000000..0eba5af
--- /dev/null
+++ b/libbsd/include/err.h
@@ -0,0 +1,83 @@
+/* $NetBSD: err.h,v 1.14 2005/02/03 04:39:32 perry Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)err.h 8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _ERR_H_
+#define _ERR_H_
+
+/*
+ * Don't use va_list in the err/warn prototypes. Va_list is typedef'd in two
+ * places (<machine/varargs.h> and <machine/stdarg.h>), so if we include one
+ * of them here we may collide with the utility's includes. It's unreasonable
+ * for utilities to have to include one of them to include err.h, so we get
+ * _BSD_VA_LIST_ from <machine/ansi.h> and use it.
+ */
+#include <machine/ansi.h>
+#include <sys/cdefs.h>
+
+#include <stdarg.h>
+
+#define __dead
+
+#define err rtems_rtld_err
+#define verr rtems_rtld_verr
+#define errx rtems_rtld_errx
+#define verrx rtems_rtld_verrx
+#define warn rtems_rtld_warn
+#define vwarn rtems_rtld_vwarn
+#define warnx rtems_rtld_warnx
+#define vwarnx rtems_rtld_vwarnx
+
+#include <setjmp.h>
+
+extern jmp_buf rtems_shell_bsd_exit_recover;
+
+__BEGIN_DECLS
+__dead void err(jmp_buf*, int, const char *, ...)
+ __attribute__((__noreturn__, __format__(__printf__, 3, 4)));
+__dead void verr(jmp_buf*, int, const char *, _BSD_VA_LIST_)
+ __attribute__((__noreturn__, __format__(__printf__, 3, 0)));
+__dead void errx(jmp_buf*, int, const char *, ...)
+ __attribute__((__noreturn__, __format__(__printf__, 3, 4)));
+__dead void verrx(jmp_buf*, int, const char *, _BSD_VA_LIST_)
+ __attribute__((__noreturn__, __format__(__printf__, 3, 0)));
+void warn(const char *, ...)
+ __attribute__((__format__(__printf__, 1, 2)));
+void vwarn(const char *, _BSD_VA_LIST_)
+ __attribute__((__format__(__printf__, 1, 0)));
+void warnx(const char *, ...)
+ __attribute__((__format__(__printf__, 1, 2)));
+void vwarnx(const char *, _BSD_VA_LIST_)
+ __attribute__((__format__(__printf__, 1, 0)));
+__END_DECLS
+
+#endif /* !_ERR_H_ */
diff --git a/libbsd/include/link.h b/libbsd/include/link.h
new file mode 100644
index 0000000..c93efd9
--- /dev/null
+++ b/libbsd/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/libbsd/include/link_elf.h b/libbsd/include/link_elf.h
new file mode 100644
index 0000000..7236b5d
--- /dev/null
+++ b/libbsd/include/link_elf.h
@@ -0,0 +1,36 @@
+/* $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>
+
+typedef struct link_map {
+ caddr_t l_addr; /* Base Address of library */
+#ifdef __mips__
+ caddr_t l_offs; /* Load Offset of library */
+#endif
+ const char *l_name; /* Absolute Path to Library */
+ void *l_ld; /* Pointer to .dynamic in memory */
+ struct link_map *l_next; /* linked list of of mapped libs */
+ struct link_map *l_prev;
+} Link_map;
+
+struct r_debug {
+ int r_version; /* not used */
+ struct link_map *r_map; /* list of loaded images */
+ void (*r_brk)(void); /* pointer to break point */
+ enum {
+ RT_CONSISTENT, /* things are stable */
+ RT_ADD, /* adding a shared library */
+ RT_DELETE /* removing a shared library */
+ } r_state;
+};
+
+#endif /* _LINK_ELF_H_ */
diff --git a/libbsd/include/sys/ansi.h b/libbsd/include/sys/ansi.h
new file mode 100644
index 0000000..9dfe42d
--- /dev/null
+++ b/libbsd/include/sys/ansi.h
@@ -0,0 +1,63 @@
+/* $NetBSD: ansi.h,v 1.10 2004/04/21 01:05:43 christos Exp $ */
+
+/*-
+ * Copyright (c) 2000, 2001, 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jun-ichiro itojun Hagino and by Klaus Klein.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 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_ANSI_H_
+#define _SYS_ANSI_H_
+
+#include <machine/int_types.h>
+
+typedef char * __caddr_t; /* core address */
+#ifndef __rtems__
+typedef __uint32_t __gid_t; /* group id */
+typedef __uint32_t __in_addr_t; /* IP(v4) address */
+typedef __uint32_t __mode_t; /* file permissions */
+#endif
+typedef __uint16_t __in_port_t; /* "Internet" port number */
+#ifndef __rtems__
+typedef __int64_t __off_t; /* file offset */
+typedef __int32_t __pid_t; /* process id */
+#endif
+typedef __uint8_t __sa_family_t; /* socket address family */
+typedef unsigned int __socklen_t; /* socket-related datum length */
+#ifndef __rtems__
+typedef __uint32_t __uid_t; /* user id */
+#endif
+typedef __uint64_t __fsblkcnt_t; /* fs block count (statvfs) */
+typedef __uint64_t __fsfilcnt_t; /* fs file count */
+
+#endif /* !_SYS_ANSI_H_ */
diff --git a/libbsd/include/sys/cdefs.h b/libbsd/include/sys/cdefs.h
new file mode 100644
index 0000000..a257ae4
--- /dev/null
+++ b/libbsd/include/sys/cdefs.h
@@ -0,0 +1,363 @@
+/* $NetBSD: cdefs.h,v 1.59 2005/06/02 14:31:38 he Exp $ */
+
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Berkeley Software Design, Inc.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)cdefs.h 8.8 (Berkeley) 1/9/95
+ */
+
+#ifndef _SYS_CDEFS_H_
+#define _SYS_CDEFS_H_
+
+/*
+ * Macro to test if we're using a GNU C compiler of a specific vintage
+ * or later, for e.g. features that appeared in a particular version
+ * of GNU C. Usage:
+ *
+ * #if __GNUC_PREREQ__(major, minor)
+ * ...cool feature...
+ * #else
+ * ...delete feature...
+ * #endif
+ */
+#ifdef __GNUC__
+#define __GNUC_PREREQ__(x, y) \
+ ((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \
+ (__GNUC__ > (x)))
+#else
+#define __GNUC_PREREQ__(x, y) 0
+#endif
+
+#include <machine/cdefs.h>
+#ifdef __ELF__
+#include <sys/cdefs_elf.h>
+#else
+#include <sys/cdefs_aout.h>
+#endif
+
+#if defined(__cplusplus)
+#define __BEGIN_DECLS extern "C" {
+#define __END_DECLS }
+#define __static_cast(x,y) static_cast<x>(y)
+#else
+#define __BEGIN_DECLS
+#define __END_DECLS
+#define __static_cast(x,y) (x)y
+#endif
+
+/*
+ * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
+ * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
+ * The __CONCAT macro is a bit tricky -- make sure you don't put spaces
+ * in between its arguments. __CONCAT can also concatenate double-quoted
+ * strings produced by the __STRING macro, but this only works with ANSI C.
+ */
+
+#define ___STRING(x) __STRING(x)
+#define ___CONCAT(x,y) __CONCAT(x,y)
+#define __XSTRING(x) __STRING(x) /* expand x, then stringify */
+
+#ifdef __GNUC__
+# define __ASMNAME(cname) __XSTRING (__USER_LABEL_PREFIX__) cname
+#endif
+
+
+#if __STDC__ || defined(__cplusplus)
+#define __P(protos) protos /* full-blown ANSI C */
+#define __CONCAT(x,y) x ## y
+#define __STRING(x) #x
+
+#define __const const /* define reserved names to standard */
+#define __signed signed
+#define __volatile volatile
+#if defined(__cplusplus)
+#define __inline inline /* convert to C++ keyword */
+#else
+#if !defined(__GNUC__) && !defined(__lint__)
+#define __inline /* delete GCC keyword */
+#endif /* !__GNUC__ && !__lint__ */
+#endif /* !__cplusplus */
+
+#else /* !(__STDC__ || __cplusplus) */
+#define __P(protos) () /* traditional C preprocessor */
+#define __CONCAT(x,y) x/**/y
+#define __STRING(x) "x"
+
+#ifndef __GNUC__
+#define __const /* delete pseudo-ANSI C keywords */
+#define __inline
+#define __signed
+#define __volatile
+#endif /* !__GNUC__ */
+
+/*
+ * In non-ANSI C environments, new programs will want ANSI-only C keywords
+ * deleted from the program and old programs will want them left alone.
+ * Programs using the ANSI C keywords const, inline etc. as normal
+ * identifiers should define -DNO_ANSI_KEYWORDS.
+ */
+#ifndef NO_ANSI_KEYWORDS
+#define const __const /* convert ANSI C keywords */
+#define inline __inline
+#define signed __signed
+#define volatile __volatile
+#endif /* !NO_ANSI_KEYWORDS */
+#endif /* !(__STDC__ || __cplusplus) */
+
+/*
+ * Used for internal auditing of the NetBSD source tree.
+ */
+#ifdef __AUDIT__
+#define __aconst __const
+#else
+#define __aconst
+#endif
+
+/*
+ * The following macro is used to remove const cast-away warnings
+ * from gcc -Wcast-qual; it should be used with caution because it
+ * can hide valid errors; in particular most valid uses are in
+ * situations where the API requires it, not to cast away string
+ * constants. We don't use *intptr_t on purpose here and we are
+ * explicit about unsigned long so that we don't have additional
+ * dependencies.
+ */
+#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
+
+/*
+ * The following macro is used to remove the volatile cast-away warnings
+ * from gcc -Wcast-qual; as above it should be used with caution
+ * because it can hide valid errors or warnings. Valid uses include
+ * making it possible to pass a volatile pointer to memset().
+ * For the same reasons as above, we use unsigned long and not intptr_t.
+ */
+#define __UNVOLATILE(a) ((void *)(unsigned long)(volatile void *)(a))
+
+/*
+ * GCC2 provides __extension__ to suppress warnings for various GNU C
+ * language extensions under "-ansi -pedantic".
+ */
+#if !__GNUC_PREREQ__(2, 0)
+#define __extension__ /* delete __extension__ if non-gcc or gcc1 */
+#endif
+
+/*
+ * GCC1 and some versions of GCC2 declare dead (non-returning) and
+ * pure (no side effects) functions using "volatile" and "const";
+ * unfortunately, these then cause warnings under "-ansi -pedantic".
+ * GCC2 uses a new, peculiar __attribute__((attrs)) style. All of
+ * these work for GNU C++ (modulo a slight glitch in the C++ grammar
+ * in the distribution version of 2.5.5).
+ */
+#if !__GNUC_PREREQ__(2, 5)
+#define __attribute__(x) /* delete __attribute__ if non-gcc or gcc1 */
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+#define __dead __volatile
+#define __pure __const
+#endif
+#endif
+
+/* Delete pseudo-keywords wherever they are not available or needed. */
+#ifndef __dead
+#define __dead
+#define __pure
+#endif
+
+#if __GNUC_PREREQ__(2, 7)
+#define __unused __attribute__((__unused__))
+#else
+#define __unused /* delete */
+#endif
+
+#if __GNUC_PREREQ__(3, 1)
+#define __used __attribute__((__used__))
+#else
+#define __used /* delete */
+#endif
+
+#if __GNUC_PREREQ__(2, 7)
+#define __packed __attribute__((__packed__))
+#define __aligned(x) __attribute__((__aligned__(x)))
+#define __section(x) __attribute__((__section__(x)))
+#elif defined(__lint__)
+#define __packed /* delete */
+#define __aligned(x) /* delete */
+#define __section(x) /* delete */
+#else
+#define __packed error: no __packed for this compiler
+#define __aligned(x) error: no __aligned for this compiler
+#define __section(x) error: no __section for this compiler
+#endif
+
+/*
+ * C99 defines the restrict type qualifier keyword, which was made available
+ * in GCC 2.92.
+ */
+#if __STDC_VERSION__ >= 199901L
+#define __restrict restrict
+#else
+#if !__GNUC_PREREQ__(2, 92)
+#define __restrict /* delete __restrict when not supported */
+#endif
+#endif
+
+/*
+ * C99 defines __func__ predefined identifier, which was made available
+ * in GCC 2.95.
+ */
+#if !(__STDC_VERSION__ >= 199901L)
+#if __GNUC_PREREQ__(2, 6)
+#define __func__ __PRETTY_FUNCTION__
+#elif __GNUC_PREREQ__(2, 4)
+#define __func__ __FUNCTION__
+#else
+#define __func__ ""
+#endif
+#endif /* !(__STDC_VERSION__ >= 199901L) */
+
+#if defined(_KERNEL)
+#if defined(NO_KERNEL_RCSIDS)
+#undef __KERNEL_RCSID
+#define __KERNEL_RCSID(_n, _s) /* nothing */
+#endif /* NO_KERNEL_RCSIDS */
+#endif /* _KERNEL */
+
+#if !defined(_STANDALONE) && !defined(_KERNEL)
+#ifdef __GNUC__
+#define __RENAME(x) ___RENAME(x)
+#else
+#ifdef __lint__
+#define __RENAME(x) __symbolrename(x)
+#else
+#error "No function renaming possible"
+#endif /* __lint__ */
+#endif /* __GNUC__ */
+#else /* _STANDALONE || _KERNEL */
+#define __RENAME(x) no renaming in kernel or standalone environment
+#endif
+
+/*
+ * A barrier to stop the optimizer from moving code or assume live
+ * register values. This is gcc specific, the version is more or less
+ * arbitrary, might work with older compilers.
+ */
+#if __GNUC_PREREQ__(2, 95)
+#define __insn_barrier() __asm __volatile("":::"memory")
+#else
+#define __insn_barrier() /* */
+#endif
+
+/*
+ * GNU C version 2.96 adds explicit branch prediction so that
+ * the CPU back-end can hint the processor and also so that
+ * code blocks can be reordered such that the predicted path
+ * sees a more linear flow, thus improving cache behavior, etc.
+ *
+ * The following two macros provide us with a way to use this
+ * compiler feature. Use __predict_true() if you expect the expression
+ * to evaluate to true, and __predict_false() if you expect the
+ * expression to evaluate to false.
+ *
+ * A few notes about usage:
+ *
+ * * Generally, __predict_false() error condition checks (unless
+ * you have some _strong_ reason to do otherwise, in which case
+ * document it), and/or __predict_true() `no-error' condition
+ * checks, assuming you want to optimize for the no-error case.
+ *
+ * * Other than that, if you don't know the likelihood of a test
+ * succeeding from empirical or other `hard' evidence, don't
+ * make predictions.
+ *
+ * * These are meant to be used in places that are run `a lot'.
+ * It is wasteful to make predictions in code that is run
+ * seldomly (e.g. at subsystem initialization time) as the
+ * basic block reordering that this affects can often generate
+ * larger code.
+ */
+#if __GNUC_PREREQ__(2, 96)
+#define __predict_true(exp) __builtin_expect((exp) != 0, 1)
+#define __predict_false(exp) __builtin_expect((exp) != 0, 0)
+#else
+#define __predict_true(exp) (exp)
+#define __predict_false(exp) (exp)
+#endif
+
+/*
+ * Macros for manipulating "link sets". Link sets are arrays of pointers
+ * to objects, which are gathered up by the linker.
+ *
+ * Object format-specific code has provided us with the following macros:
+ *
+ * __link_set_add_text(set, sym)
+ * Add a reference to the .text symbol `sym' to `set'.
+ *
+ * __link_set_add_rodata(set, sym)
+ * Add a reference to the .rodata symbol `sym' to `set'.
+ *
+ * __link_set_add_data(set, sym)
+ * Add a reference to the .data symbol `sym' to `set'.
+ *
+ * __link_set_add_bss(set, sym)
+ * Add a reference to the .bss symbol `sym' to `set'.
+ *
+ * __link_set_decl(set, ptype)
+ * Provide an extern declaration of the set `set', which
+ * contains an array of the pointer type `ptype'. This
+ * macro must be used by any code which wishes to reference
+ * the elements of a link set.
+ *
+ * __link_set_start(set)
+ * This points to the first slot in the link set.
+ *
+ * __link_set_end(set)
+ * This points to the (non-existent) slot after the last
+ * entry in the link set.
+ *
+ * __link_set_count(set)
+ * Count the number of entries in link set `set'.
+ *
+ * In addition, we provide the following macros for accessing link sets:
+ *
+ * __link_set_foreach(pvar, set)
+ * Iterate over the link set `set'. Because a link set is
+ * an array of pointers, pvar must be declared as "type **pvar",
+ * and the actual entry accessed as "*pvar".
+ *
+ * __link_set_entry(set, idx)
+ * Access the link set entry at index `idx' from set `set'.
+ */
+#define __link_set_foreach(pvar, set) \
+ for (pvar = __link_set_start(set); pvar < __link_set_end(set); pvar++)
+
+#define __link_set_entry(set, idx) (__link_set_begin(set)[idx])
+
+#endif /* !_SYS_CDEFS_H_ */
diff --git a/libbsd/include/sys/cdefs_elf.h b/libbsd/include/sys/cdefs_elf.h
new file mode 100644
index 0000000..91903d6
--- /dev/null
+++ b/libbsd/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@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/libbsd/include/sys/exec_elf.h b/libbsd/include/sys/exec_elf.h
new file mode 100644
index 0000000..392cd33
--- /dev/null
+++ b/libbsd/include/sys/exec_elf.h
@@ -0,0 +1,1093 @@
+/* $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_MICROBLAZE 189 /* Xilinx MicroBlaze 32-bit RISC soft processor core */
+
+/* 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@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/libbsd/include/sys/featuretest.h b/libbsd/include/sys/featuretest.h
new file mode 100644
index 0000000..d9085a8
--- /dev/null
+++ b/libbsd/include/sys/featuretest.h
@@ -0,0 +1,73 @@
+/* $NetBSD: featuretest.h,v 1.7 2003/12/04 12:42:54 keihan Exp $ */
+
+/*
+ * Written by Klaus Klein <kleink@NetBSD.org>, February 2, 1998.
+ * Public domain.
+ *
+ * NOTE: Do not protect this header against multiple inclusion. Doing
+ * so can have subtle side-effects due to header file inclusion order
+ * and testing of e.g. _POSIX_SOURCE vs. _POSIX_C_SOURCE. Instead,
+ * protect each CPP macro that we want to supply.
+ */
+
+/*
+ * Feature-test macros are defined by several standards, and allow an
+ * application to specify what symbols they want the system headers to
+ * expose, and hence what standard they want them to conform to.
+ * There are two classes of feature-test macros. The first class
+ * specify complete standards, and if one of these is defined, header
+ * files will try to conform to the relevant standard. They are:
+ *
+ * ANSI macros:
+ * _ANSI_SOURCE ANSI C89
+ *
+ * POSIX macros:
+ * _POSIX_SOURCE == 1 IEEE Std 1003.1 (version?)
+ * _POSIX_C_SOURCE == 1 IEEE Std 1003.1-1990
+ * _POSIX_C_SOURCE == 2 IEEE Std 1003.2-1992
+ * _POSIX_C_SOURCE == 199309L IEEE Std 1003.1b-1993
+ * _POSIX_C_SOURCE == 199506L ISO/IEC 9945-1:1996
+ * _POSIX_C_SOURCE == 200112L IEEE Std 1003.1-2001
+ *
+ * X/Open macros:
+ * _XOPEN_SOURCE System Interfaces and Headers, Issue 4, Ver 2
+ * _XOPEN_SOURCE_EXTENDED == 1 XSH4.2 UNIX extensions
+ * _XOPEN_SOURCE == 500 System Interfaces and Headers, Issue 5
+ * _XOPEN_SOURCE == 520 Networking Services (XNS), Issue 5.2
+ * _XOPEN_SOURCE == 600 IEEE Std 1003.1-2001, XSI option
+ *
+ * NetBSD macros:
+ * _NETBSD_SOURCE == 1 Make all NetBSD features available.
+ *
+ * If more than one of these "major" feature-test macros is defined,
+ * then the set of facilities provided (and namespace used) is the
+ * union of that specified by the relevant standards, and in case of
+ * conflict, the earlier standard in the above list has precedence (so
+ * if both _POSIX_C_SOURCE and _NETBSD_SOURCE are defined, the version
+ * of rename() that's used is the POSIX one). If none of the "major"
+ * feature-test macros is defined, _NETBSD_SOURCE is assumed.
+ *
+ * There are also "minor" feature-test macros, which enable extra
+ * functionality in addition to some base standard. They should be
+ * defined along with one of the "major" macros. The "minor" macros
+ * are:
+ *
+ * _REENTRANT
+ * _ISOC99_SOURCE
+ * _LARGEFILE_SOURCE Large File Support
+ * <http://ftp.sas.com/standards/large.file/x_open.20Mar96.html>
+ */
+
+#if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE)
+#define _POSIX_C_SOURCE 1L
+#endif
+
+#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) && \
+ !defined(_XOPEN_SOURCE) && !defined(_NETBSD_SOURCE)
+#define _NETBSD_SOURCE 1
+#endif
+
+#if ((_POSIX_C_SOURCE - 0) >= 199506L || (_XOPEN_SOURCE - 0) >= 500) && \
+ !defined(_REENTRANT)
+#define _REENTRANT
+#endif
diff --git a/libbsd/include/sys/nb-queue.h b/libbsd/include/sys/nb-queue.h
new file mode 100644
index 0000000..a4aef7b
--- /dev/null
+++ b/libbsd/include/sys/nb-queue.h
@@ -0,0 +1,665 @@
+/* $NetBSD: queue.h,v 1.43 2005/10/02 15:34:42 chs Exp $ */
+
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)queue.h 8.5 (Berkeley) 8/20/94
+ */
+
+#ifndef _SYS_QUEUE_H_
+#define _SYS_QUEUE_H_
+
+/*
+ * This file defines five types of data structures: singly-linked lists,
+ * lists, simple queues, tail queues, and circular queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The
+ * elements are singly linked for minimum space and pointer manipulation
+ * overhead at the expense of O(n) removal for arbitrary elements. New
+ * elements can be added to the list after an existing element or at the
+ * head of the list. Elements being removed from the head of the list
+ * should use the explicit macro for this purpose for optimum
+ * efficiency. A singly-linked list may only be traversed in the forward
+ * direction. Singly-linked lists are ideal for applications with large
+ * datasets and few or no removals or for implementing a LIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A simple queue is headed by a pair of pointers, one the head of the
+ * list and the other to the tail of the list. The elements are singly
+ * linked to save space, so elements can only be removed from the
+ * head of the list. New elements can be added to the list after
+ * an existing element, at the head of the list, or at the end of the
+ * list. A simple queue may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * A circle queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or after
+ * an existing element, at the head of the list, or at the end of the list.
+ * A circle queue may be traversed in either direction, but has a more
+ * complex end of list detection.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ */
+
+/*
+ * List definitions.
+ */
+#define LIST_HEAD(name, type) \
+struct name { \
+ struct type *lh_first; /* first element */ \
+}
+
+#define LIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define LIST_ENTRY(type) \
+struct { \
+ struct type *le_next; /* next element */ \
+ struct type **le_prev; /* address of previous next element */ \
+}
+
+/*
+ * List functions.
+ */
+#if defined(_KERNEL) && defined(QUEUEDEBUG)
+#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field) \
+ if ((head)->lh_first && \
+ (head)->lh_first->field.le_prev != &(head)->lh_first) \
+ panic("LIST_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
+#define QUEUEDEBUG_LIST_OP(elm, field) \
+ if ((elm)->field.le_next && \
+ (elm)->field.le_next->field.le_prev != \
+ &(elm)->field.le_next) \
+ panic("LIST_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
+ if (*(elm)->field.le_prev != (elm)) \
+ panic("LIST_* back %p %s:%d", (elm), __FILE__, __LINE__);
+#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field) \
+ (elm)->field.le_next = (void *)1L; \
+ (elm)->field.le_prev = (void *)1L;
+#else
+#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)
+#define QUEUEDEBUG_LIST_OP(elm, field)
+#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field)
+#endif
+
+#ifndef __rtems__
+#define LIST_INIT(head) do { \
+ (head)->lh_first = NULL; \
+} while (/*CONSTCOND*/0)
+
+#define LIST_INSERT_AFTER(listelm, elm, field) do { \
+ QUEUEDEBUG_LIST_OP((listelm), field) \
+ if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
+ (listelm)->field.le_next->field.le_prev = \
+ &(elm)->field.le_next; \
+ (listelm)->field.le_next = (elm); \
+ (elm)->field.le_prev = &(listelm)->field.le_next; \
+} while (/*CONSTCOND*/0)
+
+#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
+ QUEUEDEBUG_LIST_OP((listelm), field) \
+ (elm)->field.le_prev = (listelm)->field.le_prev; \
+ (elm)->field.le_next = (listelm); \
+ *(listelm)->field.le_prev = (elm); \
+ (listelm)->field.le_prev = &(elm)->field.le_next; \
+} while (/*CONSTCOND*/0)
+
+#define LIST_INSERT_HEAD(head, elm, field) do { \
+ QUEUEDEBUG_LIST_INSERT_HEAD((head), (elm), field) \
+ if (((elm)->field.le_next = (head)->lh_first) != NULL) \
+ (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
+ (head)->lh_first = (elm); \
+ (elm)->field.le_prev = &(head)->lh_first; \
+} while (/*CONSTCOND*/0)
+
+#define LIST_REMOVE(elm, field) do { \
+ QUEUEDEBUG_LIST_OP((elm), field) \
+ if ((elm)->field.le_next != NULL) \
+ (elm)->field.le_next->field.le_prev = \
+ (elm)->field.le_prev; \
+ *(elm)->field.le_prev = (elm)->field.le_next; \
+ QUEUEDEBUG_LIST_POSTREMOVE((elm), field) \
+} while (/*CONSTCOND*/0)
+
+#define LIST_FOREACH(var, head, field) \
+ for ((var) = ((head)->lh_first); \
+ (var); \
+ (var) = ((var)->field.le_next))
+
+/*
+ * List access methods.
+ */
+#define LIST_EMPTY(head) ((head)->lh_first == NULL)
+#define LIST_FIRST(head) ((head)->lh_first)
+#define LIST_NEXT(elm, field) ((elm)->field.le_next)
+
+
+/*
+ * Singly-linked List definitions.
+ */
+#define SLIST_HEAD(name, type) \
+struct name { \
+ struct type *slh_first; /* first element */ \
+}
+
+#define SLIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define SLIST_ENTRY(type) \
+struct { \
+ struct type *sle_next; /* next element */ \
+}
+
+/*
+ * Singly-linked List functions.
+ */
+#define SLIST_INIT(head) do { \
+ (head)->slh_first = NULL; \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
+ (elm)->field.sle_next = (slistelm)->field.sle_next; \
+ (slistelm)->field.sle_next = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_INSERT_HEAD(head, elm, field) do { \
+ (elm)->field.sle_next = (head)->slh_first; \
+ (head)->slh_first = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_REMOVE_HEAD(head, field) do { \
+ (head)->slh_first = (head)->slh_first->field.sle_next; \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_REMOVE(head, elm, type, field) do { \
+ if ((head)->slh_first == (elm)) { \
+ SLIST_REMOVE_HEAD((head), field); \
+ } \
+ else { \
+ struct type *curelm = (head)->slh_first; \
+ while(curelm->field.sle_next != (elm)) \
+ curelm = curelm->field.sle_next; \
+ curelm->field.sle_next = \
+ curelm->field.sle_next->field.sle_next; \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_FOREACH(var, head, field) \
+ for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
+
+/*
+ * Singly-linked List access methods.
+ */
+#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
+#define SLIST_FIRST(head) ((head)->slh_first)
+#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
+
+
+/*
+ * Singly-linked Tail queue declarations.
+ */
+#define STAILQ_HEAD(name, type) \
+struct name { \
+ struct type *stqh_first; /* first element */ \
+ struct type **stqh_last; /* addr of last next element */ \
+}
+
+#define STAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).stqh_first }
+
+#define STAILQ_ENTRY(type) \
+struct { \
+ struct type *stqe_next; /* next element */ \
+}
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define STAILQ_INIT(head) do { \
+ (head)->stqh_first = NULL; \
+ (head)->stqh_last = &(head)->stqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
+ (head)->stqh_last = &(elm)->field.stqe_next; \
+ (head)->stqh_first = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.stqe_next = NULL; \
+ *(head)->stqh_last = (elm); \
+ (head)->stqh_last = &(elm)->field.stqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
+ (head)->stqh_last = &(elm)->field.stqe_next; \
+ (listelm)->field.stqe_next = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_REMOVE_HEAD(head, field) do { \
+ if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \
+ (head)->stqh_last = &(head)->stqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_REMOVE(head, elm, type, field) do { \
+ if ((head)->stqh_first == (elm)) { \
+ STAILQ_REMOVE_HEAD((head), field); \
+ } else { \
+ struct type *curelm = (head)->stqh_first; \
+ while (curelm->field.stqe_next != (elm)) \
+ curelm = curelm->field.stqe_next; \
+ if ((curelm->field.stqe_next = \
+ curelm->field.stqe_next->field.stqe_next) == NULL) \
+ (head)->stqh_last = &(curelm)->field.stqe_next; \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->stqh_first); \
+ (var); \
+ (var) = ((var)->field.stqe_next))
+
+/*
+ * Singly-linked Tail queue access methods.
+ */
+#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
+#define STAILQ_FIRST(head) ((head)->stqh_first)
+#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
+
+#endif
+
+/*
+ * Simple queue definitions.
+ */
+#define SIMPLEQ_HEAD(name, type) \
+struct name { \
+ struct type *sqh_first; /* first element */ \
+ struct type **sqh_last; /* addr of last next element */ \
+}
+
+#define SIMPLEQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).sqh_first }
+
+#define SIMPLEQ_ENTRY(type) \
+struct { \
+ struct type *sqe_next; /* next element */ \
+}
+
+/*
+ * Simple queue functions.
+ */
+#define SIMPLEQ_INIT(head) do { \
+ (head)->sqh_first = NULL; \
+ (head)->sqh_last = &(head)->sqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+ (head)->sqh_first = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.sqe_next = NULL; \
+ *(head)->sqh_last = (elm); \
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+ (listelm)->field.sqe_next = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
+ if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
+ (head)->sqh_last = &(head)->sqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_REMOVE(head, elm, type, field) do { \
+ if ((head)->sqh_first == (elm)) { \
+ SIMPLEQ_REMOVE_HEAD((head), field); \
+ } else { \
+ struct type *curelm = (head)->sqh_first; \
+ while (curelm->field.sqe_next != (elm)) \
+ curelm = curelm->field.sqe_next; \
+ if ((curelm->field.sqe_next = \
+ curelm->field.sqe_next->field.sqe_next) == NULL) \
+ (head)->sqh_last = &(curelm)->field.sqe_next; \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->sqh_first); \
+ (var); \
+ (var) = ((var)->field.sqe_next))
+
+/*
+ * Simple queue access methods.
+ */
+#define SIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL)
+#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
+#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
+
+#ifndef __rtems__
+
+/*
+ * Tail queue definitions.
+ */
+#define _TAILQ_HEAD(name, type, qual) \
+struct name { \
+ qual type *tqh_first; /* first element */ \
+ qual type *qual *tqh_last; /* addr of last next element */ \
+}
+#define TAILQ_HEAD(name, type) _TAILQ_HEAD(name, struct type,)
+
+#define TAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).tqh_first }
+
+#define _TAILQ_ENTRY(type, qual) \
+struct { \
+ qual type *tqe_next; /* next element */ \
+ qual type *qual *tqe_prev; /* address of previous next element */\
+}
+#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type,)
+
+/*
+ * Tail queue functions.
+ */
+#if defined(_KERNEL) && defined(QUEUEDEBUG)
+#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field) \
+ if ((head)->tqh_first && \
+ (head)->tqh_first->field.tqe_prev != &(head)->tqh_first) \
+ panic("TAILQ_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
+#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field) \
+ if (*(head)->tqh_last != NULL) \
+ panic("TAILQ_INSERT_TAIL %p %s:%d", (head), __FILE__, __LINE__);
+#define QUEUEDEBUG_TAILQ_OP(elm, field) \
+ if ((elm)->field.tqe_next && \
+ (elm)->field.tqe_next->field.tqe_prev != \
+ &(elm)->field.tqe_next) \
+ panic("TAILQ_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
+ if (*(elm)->field.tqe_prev != (elm)) \
+ panic("TAILQ_* back %p %s:%d", (elm), __FILE__, __LINE__);
+#define QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field) \
+ if ((elm)->field.tqe_next == NULL && \
+ (head)->tqh_last != &(elm)->field.tqe_next) \
+ panic("TAILQ_PREREMOVE head %p elm %p %s:%d", \
+ (head), (elm), __FILE__, __LINE__);
+#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field) \
+ (elm)->field.tqe_next = (void *)1L; \
+ (elm)->field.tqe_prev = (void *)1L;
+#else
+#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)
+#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)
+#define QUEUEDEBUG_TAILQ_OP(elm, field)
+#define QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field)
+#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)
+#endif
+
+#define TAILQ_INIT(head) do { \
+ (head)->tqh_first = NULL; \
+ (head)->tqh_last = &(head)->tqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_HEAD(head, elm, field) do { \
+ QUEUEDEBUG_TAILQ_INSERT_HEAD((head), (elm), field) \
+ if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
+ (head)->tqh_first->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (head)->tqh_first = (elm); \
+ (elm)->field.tqe_prev = &(head)->tqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_TAIL(head, elm, field) do { \
+ QUEUEDEBUG_TAILQ_INSERT_TAIL((head), (elm), field) \
+ (elm)->field.tqe_next = NULL; \
+ (elm)->field.tqe_prev = (head)->tqh_last; \
+ *(head)->tqh_last = (elm); \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ QUEUEDEBUG_TAILQ_OP((listelm), field) \
+ if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
+ (elm)->field.tqe_next->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (listelm)->field.tqe_next = (elm); \
+ (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
+ QUEUEDEBUG_TAILQ_OP((listelm), field) \
+ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
+ (elm)->field.tqe_next = (listelm); \
+ *(listelm)->field.tqe_prev = (elm); \
+ (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_REMOVE(head, elm, field) do { \
+ QUEUEDEBUG_TAILQ_PREREMOVE((head), (elm), field) \
+ QUEUEDEBUG_TAILQ_OP((elm), field) \
+ if (((elm)->field.tqe_next) != NULL) \
+ (elm)->field.tqe_next->field.tqe_prev = \
+ (elm)->field.tqe_prev; \
+ else \
+ (head)->tqh_last = (elm)->field.tqe_prev; \
+ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
+ QUEUEDEBUG_TAILQ_POSTREMOVE((elm), field); \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->tqh_first); \
+ (var); \
+ (var) = ((var)->field.tqe_next))
+
+#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
+ for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
+ (var); \
+ (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
+
+/*
+ * Tail queue access methods.
+ */
+#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
+#define TAILQ_FIRST(head) ((head)->tqh_first)
+#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#define TAILQ_LAST(head, headname) \
+ (*(((struct headname *)((head)->tqh_last))->tqh_last))
+#define TAILQ_PREV(elm, headname, field) \
+ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+
+/*
+ * Circular queue definitions.
+ */
+#if defined(_KERNEL) && defined(QUEUEDEBUG)
+#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field) \
+ if ((head)->cqh_first != (void *)(head) && \
+ (head)->cqh_first->field.cqe_prev != (void *)(head)) \
+ panic("CIRCLEQ head forw %p %s:%d", (head), \
+ __FILE__, __LINE__); \
+ if ((head)->cqh_last != (void *)(head) && \
+ (head)->cqh_last->field.cqe_next != (void *)(head)) \
+ panic("CIRCLEQ head back %p %s:%d", (head), \
+ __FILE__, __LINE__);
+#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field) \
+ if ((elm)->field.cqe_next == (void *)(head)) { \
+ if ((head)->cqh_last != (elm)) \
+ panic("CIRCLEQ elm last %p %s:%d", (elm), \
+ __FILE__, __LINE__); \
+ } else { \
+ if ((elm)->field.cqe_next->field.cqe_prev != (elm)) \
+ panic("CIRCLEQ elm forw %p %s:%d", (elm), \
+ __FILE__, __LINE__); \
+ } \
+ if ((elm)->field.cqe_prev == (void *)(head)) { \
+ if ((head)->cqh_first != (elm)) \
+ panic("CIRCLEQ elm first %p %s:%d", (elm), \
+ __FILE__, __LINE__); \
+ } else { \
+ if ((elm)->field.cqe_prev->field.cqe_next != (elm)) \
+ panic("CIRCLEQ elm prev %p %s:%d", (elm), \
+ __FILE__, __LINE__); \
+ }
+#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field) \
+ (elm)->field.cqe_next = (void *)1L; \
+ (elm)->field.cqe_prev = (void *)1L;
+#else
+#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field)
+#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field)
+#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field)
+#endif
+
+#define CIRCLEQ_HEAD(name, type) \
+struct name { \
+ struct type *cqh_first; /* first element */ \
+ struct type *cqh_last; /* last element */ \
+}
+
+#define CIRCLEQ_HEAD_INITIALIZER(head) \
+ { (void *)&head, (void *)&head }
+
+#define CIRCLEQ_ENTRY(type) \
+struct { \
+ struct type *cqe_next; /* next element */ \
+ struct type *cqe_prev; /* previous element */ \
+}
+
+/*
+ * Circular queue functions.
+ */
+#define CIRCLEQ_INIT(head) do { \
+ (head)->cqh_first = (void *)(head); \
+ (head)->cqh_last = (void *)(head); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
+ QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field) \
+ (elm)->field.cqe_next = (listelm)->field.cqe_next; \
+ (elm)->field.cqe_prev = (listelm); \
+ if ((listelm)->field.cqe_next == (void *)(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (listelm)->field.cqe_next->field.cqe_prev = (elm); \
+ (listelm)->field.cqe_next = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
+ QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
+ QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field) \
+ (elm)->field.cqe_next = (listelm); \
+ (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
+ if ((listelm)->field.cqe_prev == (void *)(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (listelm)->field.cqe_prev->field.cqe_next = (elm); \
+ (listelm)->field.cqe_prev = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
+ QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
+ (elm)->field.cqe_next = (head)->cqh_first; \
+ (elm)->field.cqe_prev = (void *)(head); \
+ if ((head)->cqh_last == (void *)(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (head)->cqh_first->field.cqe_prev = (elm); \
+ (head)->cqh_first = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
+ QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
+ (elm)->field.cqe_next = (void *)(head); \
+ (elm)->field.cqe_prev = (head)->cqh_last; \
+ if ((head)->cqh_first == (void *)(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (head)->cqh_last->field.cqe_next = (elm); \
+ (head)->cqh_last = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_REMOVE(head, elm, field) do { \
+ QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
+ QUEUEDEBUG_CIRCLEQ_ELM((head), (elm), field) \
+ if ((elm)->field.cqe_next == (void *)(head)) \
+ (head)->cqh_last = (elm)->field.cqe_prev; \
+ else \
+ (elm)->field.cqe_next->field.cqe_prev = \
+ (elm)->field.cqe_prev; \
+ if ((elm)->field.cqe_prev == (void *)(head)) \
+ (head)->cqh_first = (elm)->field.cqe_next; \
+ else \
+ (elm)->field.cqe_prev->field.cqe_next = \
+ (elm)->field.cqe_next; \
+ QUEUEDEBUG_CIRCLEQ_POSTREMOVE((elm), field) \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->cqh_first); \
+ (var) != (void *)(head); \
+ (var) = ((var)->field.cqe_next))
+
+#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
+ for ((var) = ((head)->cqh_last); \
+ (var) != (void *)(head); \
+ (var) = ((var)->field.cqe_prev))
+
+/*
+ * Circular queue access methods.
+ */
+#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
+#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
+#define CIRCLEQ_LAST(head) ((head)->cqh_last)
+#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
+#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
+
+#endif
+#endif /* !_SYS_QUEUE_H_ */
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..cb24849
--- /dev/null
+++ b/main.c
@@ -0,0 +1,463 @@
+/*
+ * $Id$
+ *
+ * RTEMS Project (http://www.rtems.org/)
+ *
+ * Copyright 2010 Chris Johns (chrisj@rtems.org)
+ */
+
+/**
+ * Run Time Linker test program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <setjmp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <termios.h>
+
+#include <dlfcn.h>
+
+#include <rtems.h>
+#include <rtems/bdbuf.h>
+#include <rtems/blkdev.h>
+#include <rtems/diskdevs.h>
+#include <rtems/error.h>
+#include <rtems/fsmount.h>
+#include <rtems/ramdisk.h>
+#include <rtems/shell.h>
+#include <rtems/untar.h>
+
+#if RTEMS_APP_FLASHDISK
+#include <rtems/flashdisk.h>
+#include <libchip/am29lv160.h>
+#endif
+
+#if RTEMS_APP_IDEDISK
+#include <libchip/ide_ctrl.h>
+#include <libchip/ata.h>
+#endif
+
+#if pc586
+#include "pc386-gdb.h"
+int remote_debug;
+#endif
+
+#include <rtl-shell.h>
+#include <rtl-trace.h>
+
+/*
+ * The tarfile is built automatically externally so we need to account
+ * for the leading symbol on the names.
+ */
+#if defined(__sh__)
+ #define SYM(_x) _x
+#else
+ #define SYM(_x) _ ## _x
+#endif
+
+/**
+ * The shell-init tarfile parameters.
+ */
+extern int SYM(binary_fs_root_tar_start);
+extern int SYM(binary_fs_root_tar_size);
+
+#define TARFILE_START SYM(binary_fs_root_tar_start)
+#define TARFILE_SIZE SYM(binary_fs_root_tar_size)
+
+/**
+ * The RAM Disk configuration.
+ */
+rtems_ramdisk_config rtems_ramdisk_configuration[] =
+{
+ {
+ block_size: 512,
+ block_num: 3 * 1024 * 2,
+ location: NULL
+ }
+};
+
+/**
+ * The number of RAM Disk configurations.
+ */
+size_t rtems_ramdisk_configuration_size = 1;
+
+/**
+ * Create the RAM Disk Driver entry.
+ */
+rtems_driver_address_table rtems_ramdisk_io_ops = {
+ initialization_entry: ramdisk_initialize,
+ open_entry: rtems_blkdev_generic_open,
+ close_entry: rtems_blkdev_generic_close,
+ read_entry: rtems_blkdev_generic_read,
+ write_entry: rtems_blkdev_generic_write,
+ control_entry: rtems_blkdev_generic_ioctl
+};
+
+#if RTEMS_APP_FLASHDISK
+/**
+ * The Flash Device Driver configuration.
+ */
+const rtems_am29lv160_config rtems_am29lv160_configuration[] =
+{
+ {
+ bus_8bit: 0,
+ base: (void*) 0xFFE00000
+ }
+};
+
+/**
+ * The number of AM29LV160 configurations.
+ */
+uint32_t rtems_am29lv160_configuration_size = 1;
+
+/**
+ * The Flash Segment descriptor. The mcf5235 board uses the
+ * bottom part of the flash for the dBug monitor.
+ */
+const rtems_fdisk_segment_desc rtems_mcf5235_segment_descriptor[] =
+{
+ {
+ count: 26,
+ segment: 0,
+ offset: 0x00050000,
+ size: RTEMS_FDISK_KBYTES (64)
+ }
+};
+
+/**
+ * The Flash Device descriptor.
+ */
+const rtems_fdisk_device_desc rtems_mcf5235_device_descriptor[] =
+{
+ {
+ segment_count: 1,
+ segments: &rtems_mcf5235_segment_descriptor[0],
+ flash_ops: &rtems_am29lv160_handlers
+ }
+};
+
+/**
+ * The Flash Disk configuration.
+ */
+const rtems_flashdisk_config rtems_flashdisk_configuration[] =
+{
+ {
+ block_size: 512,
+ device_count: 1,
+ devices: &rtems_mcf5235_device_descriptor[0],
+ flags: RTEMS_FDISK_BLANK_CHECK_BEFORE_WRITE,
+ unavail_blocks: 256,
+ compact_segs: 100,
+ avail_compact_segs: 100,
+ info_level: 0
+ }
+};
+
+/**
+ * The number of Flash Disk configurations.
+ */
+size_t rtems_flashdisk_configuration_size = 1;
+
+/**
+ * Create the Flash Disk Driver entry.
+ */
+rtems_driver_address_table rtems_flashdisk_io_ops = {
+ initialization_entry: rtems_fdisk_initialize,
+ open_entry: rtems_blkdev_generic_open,
+ close_entry: rtems_blkdev_generic_close,
+ read_entry: rtems_blkdev_generic_read,
+ write_entry: rtems_blkdev_generic_write,
+ control_entry: rtems_blkdev_generic_ioctl
+};
+#endif
+
+#if RTEMS_APP_IDEDISK
+/**
+ * Create the IDE Disk Driver entry.
+ */
+rtems_driver_address_table rtems_idedisk_io_ops = {
+ initialization_entry: rtems_ata_initialize,
+ open_entry: rtems_blkdev_generic_open,
+ close_entry: rtems_blkdev_generic_close,
+ read_entry: rtems_blkdev_generic_read,
+ write_entry: rtems_blkdev_generic_write,
+ control_entry: rtems_blkdev_generic_ioctl
+};
+#endif
+
+/**
+ * Let the IO system allocation the next available major number.
+ */
+#define RTEMS_DRIVER_AUTO_MAJOR (0)
+
+/**
+ * Start the RTEMS Shell.
+ */
+void
+shell_start (void)
+{
+ rtems_status_code sc;
+ printf ("Starting shell....\n\n");
+ sc = rtems_shell_init ("fstst", 60 * 1024, 150, "/dev/console", 0, 1, NULL);
+ if (sc != RTEMS_SUCCESSFUL)
+ printf ("error: starting shell: %s (%d)\n", rtems_status_text (sc), sc);
+}
+
+/**
+ * Run the /shell-init script.
+ */
+void
+shell_init_script (void)
+{
+ rtems_status_code sc;
+ printf ("Running /shell-init....\n\n");
+ sc = rtems_shell_script ("fstst", 60 * 1024, 160, "/shell-init", "stdout",
+ 0, 1, 1);
+ if (sc != RTEMS_SUCCESSFUL)
+ printf ("error: running shell script: %s (%d)\n", rtems_status_text (sc), sc);
+}
+
+int
+setup_ramdisk (void)
+{
+ rtems_device_major_number major;
+ rtems_status_code sc;
+
+ /*
+ * Register the RAM Disk driver.
+ */
+ printf ("Register RAM Disk Driver: ");
+ sc = rtems_io_register_driver (RTEMS_DRIVER_AUTO_MAJOR,
+ &rtems_ramdisk_io_ops,
+ &major);
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ printf ("error: ramdisk driver not initialised: %s\n",
+ rtems_status_text (sc));
+ return 1;
+ }
+
+ printf ("successful\n");
+
+ return 0;
+}
+
+int
+setup_flashdisk (void)
+{
+#if RTEMS_APP_FLASHDISK
+ rtems_device_major_number major;
+ rtems_status_code sc;
+
+ /*
+ * Register the Flash Disk driver.
+ */
+ printf ("Register Flash Disk Driver: ");
+ sc = rtems_io_register_driver (RTEMS_DRIVER_AUTO_MAJOR,
+ &rtems_flashdisk_io_ops,
+ &major);
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ printf ("error: flashdisk driver not initialised: %s\n",
+ rtems_status_text (sc));
+ return 1;
+ }
+
+ printf ("successful\n");
+#endif
+ return 0;
+}
+
+#if RTEMS_APP_IDEDISK
+extern rtems_status_code rtems_ide_part_table_initialize (const char* );
+#endif
+
+int
+setup_idedisk (const char* path)
+{
+#if RTEMS_APP_IDEDISK
+ rtems_status_code sc;
+
+ /*
+ * Register the IDE Disk driver.
+ */
+ printf ("Read IDE Disk Partition Table: ");
+ sc = rtems_ide_part_table_initialize (path);
+ if (sc != RTEMS_SUCCESSFUL)
+ printf ("error: ide partition table not found: %s\n",
+ rtems_status_text (sc));
+ else
+ printf ("successful\n");
+
+#endif
+ return 0;
+}
+
+int
+setup_rootfs (void)
+{
+ rtems_status_code sc;
+
+ printf("Loading filesystem: ");
+
+ sc = Untar_FromMemory((void *)(&TARFILE_START), (size_t)&TARFILE_SIZE);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ printf ("error: untar failed: %s\n", rtems_status_text (sc));
+ return 1;
+ }
+
+ printf ("successful\n");
+
+ return 0;
+}
+
+int
+shell_flash_erase (int argc, char* argv[])
+{
+#if RTEMS_APP_FLASHDISK
+ const char* driver = NULL;
+ int arg;
+ int fd;
+
+ for (arg = 1; arg < argc; arg++)
+ {
+ if (argv[arg][0] == '-')
+ {
+ printf ("error: invalid option: %s\n", argv[arg]);
+ return 1;
+ }
+ else
+ {
+ if (!driver)
+ driver = argv[arg];
+ else
+ {
+ printf ("error: only one driver name allowed: %s\n", argv[arg]);
+ return 1;
+ }
+ }
+ }
+
+ printf ("erase flash disk: %s\n", driver);
+
+ fd = open (driver, O_WRONLY, 0);
+ if (fd < 0)
+ {
+ printf ("error: flash driver open failed: %s\n", strerror (errno));
+ return 1;
+ }
+
+ if (ioctl (fd, RTEMS_FDISK_IOCTL_ERASE_DISK) < 0)
+ {
+ printf ("error: flash driver erase failed: %s\n", strerror (errno));
+ return 1;
+ }
+
+ close (fd);
+
+ printf ("flash disk erased successful\n");
+#endif
+ return 0;
+}
+
+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[]);
+
+int
+main (int argc, char* argv[])
+{
+ struct termios term;
+ int ret;
+
+#if pc586
+ int arg;
+ for (arg = 1; arg < argc; arg++)
+ if (strcmp (argv[arg], "--gdb") == 0)
+ pc386_gdb_init ();
+#endif
+
+ if (tcgetattr(fileno(stdout), &term) < 0)
+ printf ("error: cannot get terminal attributes: %s\n", strerror (errno));
+ cfsetispeed (&term, B115200);
+ cfsetospeed (&term, B115200);
+ if (tcsetattr (fileno(stdout), TCSADRAIN, &term) < 0)
+ printf ("error: cannot set terminal attributes: %s\n", strerror (errno));
+
+ if (tcgetattr(fileno(stdin), &term) < 0)
+ printf ("error: cannot get terminal attributes: %s\n", strerror (errno));
+ cfsetispeed (&term, B115200);
+ cfsetospeed (&term, B115200);
+ if (tcsetattr (fileno(stdin), TCSADRAIN, &term) < 0)
+ printf ("error: cannot set terminal attributes: %s\n", strerror (errno));
+
+ printf ("\nRTEMS Run Time Link Editor Test, Version " \
+ PACKAGE_VERSION "\n\n");
+
+ ret = setup_ramdisk ();
+ if (ret)
+ exit (ret);
+
+ ret = setup_flashdisk ();
+ if (ret)
+ exit (ret);
+
+ ret = setup_idedisk ("/dev/hda");
+ if (ret)
+ exit (ret);
+
+ ret = setup_idedisk ("/dev/hdb");
+ if (ret)
+ exit (ret);
+
+ ret = setup_rootfs ();
+ if (ret)
+ exit (ret);
+
+#if RTEMS_RTL_TRACE
+ rtems_shell_add_cmd ("rtl-trace", "misc",
+ "RLT trace",
+ rtems_rtl_trace_shell_command);
+#endif
+
+ rtems_shell_add_cmd ("fderase", "misc",
+ "fderase driver", shell_flash_erase);
+ rtems_shell_add_cmd ("rtl", "misc",
+ "Runtime Linker", rtems_rtl_shell_command);
+ rtems_shell_add_cmd ("dlo", "misc",
+ "load object file", shell_dlopen);
+ rtems_shell_add_cmd ("dlc", "misc",
+ "unload object file", shell_dlclose);
+ rtems_shell_add_cmd ("dls", "misc",
+ "symbol search file", shell_dlsym);
+ rtems_shell_add_cmd ("dlx", "misc",
+ "execute a call to the symbol", shell_dlcall);
+
+ shell_init_script ();
+
+ while (true)
+ shell_start ();
+
+ rtems_task_delete (RTEMS_SELF);
+
+ return 0;
+}
+
+#if pc586
+void
+rtems_fatal_error_occurred (uint32_t code)
+{
+ printf ("fatal error: %08lx\n", code);
+ for (;;);
+}
+#endif
diff --git a/mcf5235-gdbinit-script b/mcf5235-gdbinit-script
new file mode 100644
index 0000000..f7eca8c
--- /dev/null
+++ b/mcf5235-gdbinit-script
@@ -0,0 +1,58 @@
+#
+# Connect to the target.
+#
+target remote | m68k-bdm-gdbserver pipe 253-005
+#target remote | m68k-bdm-gdbserver pipe /dev/tblcf1
+#target remote :7777
+#target remote me:7777
+#target remote lapdog:7777
+
+#
+# The console loop in the Axman dbug monitor. Found by trial and error
+# with the debugger.
+#
+thb *0xffe254c0
+
+#
+# Show the exception stack frame.
+#
+define show-exception-sframe
+ set $frsr = *(unsigned short *)((unsigned long)$sp + 2)
+ set $frpc = *(unsigned long *)((unsigned long)$sp + 4)
+ set $frfvo = *(unsigned short *)((unsigned long)$sp + 0)
+ set $frcode = $frfvo >> 12
+ set $frvect = ($frfvo & 0xFFF) >> 2
+ set $frstatus = ((($frfvo >> 10) & 3) << 2) | ($frfvo & 3)
+ printf "EXCEPTION -- SR:0x%X PC:0x%X FRAME:0x%x VECTOR:%d STATUS:%d\n", $frsr, $frpc, $frcode, $frvect, $frstatus
+ if $frstatus == 4
+ printf " Fault Type: Error on instruction fetch"
+ end
+ if $frstatus == 8
+ printf " Fault Type: Error on operand write"
+ end
+ if $frstatus == 12
+ printf " Fault Type: Error on operand read"
+ end
+ if $frstatus == 9
+ printf " Fault Type: Attempted write to write-protected space"
+ end
+end
+
+#
+# Run to initialise the RAM. The target will stop when the
+# breakpoint is hit. Load the program.
+#
+c
+load
+
+#
+# Break on an exception.
+#
+b _uhoh
+b rtems_fatal_error_occurred
+
+#
+# Travel to main then stop.
+#
+tb main
+c
diff --git a/mksyms.awk b/mksyms.awk
new file mode 100644
index 0000000..ce41567
--- /dev/null
+++ b/mksyms.awk
@@ -0,0 +1,115 @@
+#
+# COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+#
+# $Id$
+#
+# Covert the list of symbols into a C structure.
+#
+#
+
+function c_header()
+{
+ print ("/*");
+ print (" * RTEMS Global Symbol Table");
+ print (" * Automatically generated. Do not edit, just regenerate.");
+ print (" */");
+ print ("");
+ print ("extern unsigned char __rtems_rtl_base_globals[];");
+ print ("extern unsigned int __rtems_rtl_base_globals_size;");
+ print ("");
+ print ("asm(\" .align 4\");");
+ print ("asm(\"__rtems_rtl_base_globals:\");");
+}
+
+function c_trailer()
+{
+ print ("asm(\" .byte 0\");");
+ print ("asm(\" .align 0\");");
+ print ("asm(\" .ascii \\\"\\xde\\xad\\xbe\\xef\\\"\");");
+ print ("asm(\" .align 4\");");
+ print ("asm(\"__rtems_rtl_base_globals_size:\");");
+ print ("asm(\" .long __rtems_rtl_base_globals_size - __rtems_rtl_base_globals\");");
+ print ("");
+ print ("void rtems_rtl_base_sym_global_add (const unsigned char* , unsigned int );");
+}
+
+function c_rtl_call_body()
+{
+ print ("{");
+ print (" rtems_rtl_base_sym_global_add (__rtems_rtl_base_globals,");
+ print (" __rtems_rtl_base_globals_size);");
+ print ("}");
+}
+
+function c_constructor_trailer()
+{
+ c_trailer();
+ print ("static void init(void) __attribute__ ((constructor));");
+ print ("static void init(void)");
+ c_rtl_call_body();
+}
+
+function c_embedded_trailer()
+{
+ c_trailer();
+ print ("void rtems_rtl_base_global_syms_init(void)");
+ c_rtl_call_body();
+}
+
+BEGIN {
+ FS = "[ \t\n]";
+ OFS = " ";
+ embed = 0
+ for (a = 0; a < ARGC; ++a)
+ {
+ if (ARGV[a] == "--embed")
+ {
+ embed = 1
+ delete ARGV[a];
+ }
+ }
+ c_header();
+ syms = 0
+}
+END {
+ for (s = 0; s < syms; ++s)
+ {
+ printf ("asm(\" .asciz \\\"%s\\\"\");\n", symbols[s]);
+ if (embed)
+ {
+ printf ("asm(\" .align 0\");\n");
+ printf ("asm(\" .long %s\");\n", symbols[s]);
+ }
+ else
+ printf ("asm(\" .long 0x%s\");\n", addresses[s]);
+ }
+ if (embed)
+ c_embedded_trailer();
+ else
+ c_constructor_trailer();
+}
+
+#
+# Parse the output of 'nm'
+#
+
+{
+ #
+ # We need 3 fields
+ #
+ if (NF == 3)
+ {
+ if (($3 != "__DTOR_END__") ||
+ ($3 != "__CTOR_END__") ||
+ ($3 != "__DYNAMIC"))
+ {
+ symbols[syms] = $3;
+ addresses[syms] = $1;
+ ++syms;
+ }
+ }
+}
diff --git a/mmap-internal.h b/mmap-internal.h
new file mode 100644
index 0000000..ec36e3a
--- /dev/null
+++ b/mmap-internal.h
@@ -0,0 +1,37 @@
+/*
+ * mmap() - POSIX 1003.1b 6.3.1 - map pages of memory
+ *
+ * COPYRIGHT (c) 2010.
+ * Chris Johns (chrisj@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.
+ *
+ * $Id$
+ */
+
+#ifndef MMAP_INTERNAL_H
+
+#include <stdint.h>
+
+#include <rtems.h>
+#include <rtems/chain.h>
+
+/**
+ * Every mmap'ed region has a mapping.
+ */
+typedef struct mmap_mappings_s {
+ rtems_chain_node node; /**< The mapping chain's node */
+ void* addr; /**< The address of the mapped memory */
+ size_t len; /**< The length of memory mapped */
+ int flags; /**< The mapping flags */
+} mmap_mapping;
+
+extern rtems_chain_control mmap_mappings;
+
+bool mmap_mappings_lock_obtain( void );
+bool mmap_mappings_lock_release( void );
+
+
+#endif
diff --git a/mmap.c b/mmap.c
new file mode 100644
index 0000000..9717c48
--- /dev/null
+++ b/mmap.c
@@ -0,0 +1,235 @@
+/*
+ * mmap() - POSIX 1003.1b 6.3.1 - map pages of memory
+ *
+ * COPYRIGHT (c) 2010.
+ * Chris Johns (chrisj@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.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "rtems/libio_.h"
+
+#include "mmap-internal.h"
+
+#define RTEMS_MUTEX_ATTRIBS \
+ (RTEMS_PRIORITY | RTEMS_SIMPLE_BINARY_SEMAPHORE | \
+ RTEMS_NO_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL)
+
+/**
+ * Mmap chain of mappings.
+ */
+rtems_chain_control mmap_mappings;
+
+/**
+ * The id of the MMAP lock.
+ */
+static rtems_id mmap_mappings_lock;
+
+/**
+ * Create the lock.
+ */
+static
+bool mmap_mappings_lock_create(
+ void
+)
+{
+ /*
+ * Lock the mapping table. We only create a lock if a call is made. First we
+ * test if a mapping lock is present. If one is present we lock it. If not
+ * the libio lock is locked and we then test the mapping lock again. If not
+ * present we create the mapping lock then release libio lock.
+ */
+ if ( mmap_mappings_lock == 0 ) {
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ rtems_chain_initialize_empty( &mmap_mappings );
+ rtems_semaphore_obtain( rtems_libio_semaphore,
+ RTEMS_WAIT, RTEMS_NO_TIMEOUT );
+ if ( mmap_mappings_lock == 0 )
+ sc = rtems_semaphore_create( rtems_build_name( 'M', 'M', 'A', 'P' ),
+ 1,
+ RTEMS_MUTEX_ATTRIBS,
+ RTEMS_NO_PRIORITY,
+ &mmap_mappings_lock );
+ rtems_semaphore_release( rtems_libio_semaphore );
+ if ( sc != RTEMS_SUCCESSFUL ) {
+ errno = EINVAL;
+ return false;
+ }
+ }
+ return true;
+}
+
+bool mmap_mappings_lock_obtain(
+ void
+)
+{
+ if ( mmap_mappings_lock_create( ) ) {
+ rtems_status_code sc;
+ sc = rtems_semaphore_obtain( mmap_mappings_lock,
+ RTEMS_WAIT, RTEMS_NO_TIMEOUT );
+ if ( sc != RTEMS_SUCCESSFUL ) {
+ errno = EINVAL;
+ return false;
+ }
+ }
+ return true;
+}
+
+bool mmap_mappings_lock_release(
+ void
+)
+{
+ rtems_status_code sc;
+ sc = rtems_semaphore_release( mmap_mappings_lock );
+ if (( sc != RTEMS_SUCCESSFUL ) && ( errno == 0 )) {
+ errno = EINVAL;
+ return false;
+ }
+ return true;
+}
+
+void *mmap(
+ void *addr, size_t len, int prot, int flags, int fildes, off_t off
+)
+{
+ struct stat sb;
+ mmap_mapping* mapping;
+ ssize_t r;
+
+ /*
+ * Clear errno.
+ */
+ errno = 0;
+
+ /*
+ * Get a stat of the file to get the dev + inode number and to make sure the
+ * fd is ok. The normal libio calls cannot be used because we need to return
+ * MAP_FAILED on error and they return -1 directly without coming back to
+ * here.
+ */
+ if ( fstat( fildes, &sb ) < 0 ) {
+ errno = EBADF;
+ return MAP_FAILED;
+ }
+
+ if ( len == 0 ) {
+ errno = EINVAL;
+ return MAP_FAILED;
+ }
+
+ /*
+ * Check the type of file we have and make sure it is supported.
+ */
+ if ( S_ISDIR( sb.st_mode ) || S_ISLNK( sb.st_mode )) {
+ errno = ENODEV;
+ return MAP_FAILED;
+ }
+
+ /*
+ * We can provide read, write and execute because the memory in RTEMS does
+ * not normally have protections but we cannot hide access to memory.
+ */
+ if ( prot == PROT_NONE ) {
+ errno = EINVAL;
+ return MAP_FAILED;
+ }
+
+ /*
+ * Check to see if the mapping is valid for the file.
+ */
+ if ( S_ISREG( sb.st_mode )
+ && (( off >= sb.st_size ) || (( off + len ) >= sb.st_size ))) {
+ errno = EOVERFLOW;
+ return MAP_FAILED;
+ }
+
+ /*
+ * Obtain the mmap lock. Sets errno on failure.
+ */
+ if ( !mmap_mappings_lock_obtain( ) )
+ return MAP_FAILED;
+
+ if (( flags & MAP_FIXED ) == MAP_FIXED ) {
+ rtems_chain_node* node = rtems_chain_first (&mmap_mappings);
+ while ( !rtems_chain_is_tail( &mmap_mappings, node )) {
+ /*
+ * If the map is fixed see if this address is already mapped. At this
+ * point in time if there is an overlap in the mappings we return an
+ * error.
+ */
+ mapping = (mmap_mapping*) node;
+ if ( ( addr >= mapping->addr ) &&
+ ( addr < ( mapping->addr + mapping->len )) ) {
+ mmap_mappings_lock_release( );
+ errno = ENXIO;
+ return MAP_FAILED;
+ }
+ node = rtems_chain_next( node );
+ }
+ }
+
+ mapping = malloc( sizeof( mmap_mapping ));
+ if ( !mapping ) {
+ mmap_mappings_lock_release( );
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ memset( mapping, 0, sizeof( mmap_mapping ));
+
+ mapping->len = len;
+ mapping->flags = flags;
+
+ if (( flags & MAP_FIXED ) != MAP_FIXED ) {
+ mapping->addr = malloc( len );
+ if ( !mapping->addr ) {
+ mmap_mappings_lock_release( );
+ free( mapping );
+ errno = ENOMEM;
+ return MAP_FAILED;
+ }
+
+ /*
+ * Do not seek on character devices, pipes or sockets.
+ */
+ if ( S_ISREG( sb.st_mode ) || S_ISBLK( sb.st_mode ) ) {
+ if ( lseek( fildes, off, SEEK_SET ) < 0 ) {
+ mmap_mappings_lock_release( );
+ free( mapping->addr );
+ free( mapping );
+ return MAP_FAILED;
+ }
+ }
+ }
+
+ r = read( fildes, mapping->addr, len );
+
+ if ( r != len ) {
+ mmap_mappings_lock_release( );
+ free( mapping->addr );
+ free( mapping );
+ errno = ENXIO;
+ return MAP_FAILED;
+ }
+
+ rtems_chain_append( &mmap_mappings, &mapping->node );
+
+ mmap_mappings_lock_release( );
+
+ return mapping->addr;
+}
diff --git a/munmap.c b/munmap.c
new file mode 100644
index 0000000..0dfe6a9
--- /dev/null
+++ b/munmap.c
@@ -0,0 +1,73 @@
+/*
+ * mmap() - POSIX 1003.1b 6.3.1 - map pages of memory
+ *
+ * COPYRIGHT (c) 2010.
+ * Chris Johns (chrisj@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.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+
+#include "mmap-internal.h"
+
+int munmap(
+ void *addr, size_t len
+)
+{
+ mmap_mapping* mapping;
+ rtems_chain_node* node;
+
+ /*
+ * Clear errno.
+ */
+ errno = 0;
+
+ /*
+ * Length cannot be 0.
+ */
+ if ( len == 0 ) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /*
+ * Obtain the mmap lock. Sets errno on failure.
+ */
+ if ( !mmap_mappings_lock_obtain( ))
+ return -1;
+
+ node = rtems_chain_first (&mmap_mappings);
+ while ( !rtems_chain_is_tail( &mmap_mappings, node )) {
+ /*
+ * If the map is fixed see if this address is already mapped. At this
+ * point in time if there is an overlap in the mappings we return an
+ * error.
+ */
+ mapping = (mmap_mapping*) node;
+ if ( ( addr >= mapping->addr ) &&
+ ( addr < ( mapping->addr + mapping->len )) ) {
+ rtems_chain_extract( node );
+ if (( mapping->flags & MAP_FIXED ) != MAP_FIXED ) {
+ free( mapping->addr );
+ free( mapping );
+ }
+ break;
+ }
+ node = rtems_chain_next( node );
+ }
+
+ mmap_mappings_lock_release( );
+ return 0;
+}
diff --git a/networkconfig.h b/networkconfig.h
new file mode 100644
index 0000000..20368b4
--- /dev/null
+++ b/networkconfig.h
@@ -0,0 +1,162 @@
+/*
+ * Network configuration EXAMPLE!!!
+ *
+ ************************************************************
+ * EDIT THIS FILE TO REFLECT YOUR NETWORK CONFIGURATION *
+ * BEFORE RUNNING ANY RTEMS PROGRAMS WHICH USE THE NETWORK! *
+ ************************************************************
+ *
+ * $Id: networkconfig.h,v 1.9 2007/07/18 19:35:18 joel Exp $
+ */
+
+#ifndef _CONFIGURE_NETWORKCONFIG_H_
+#define _CONFIGURE_NETWORKCONFIG_H_
+
+/*
+ * The following will normally be set by the BSP if it supports
+ * a single network device driver. In the event, it supports
+ * multiple network device drivers, then the user's default
+ * network device driver will have to be selected by a BSP
+ * specific mechanism.
+ */
+
+#if !defined(CONFIGURE_NETWORK_DRIVER_NAME)
+#warning "CONFIGURE_NETWORK_DRIVER_NAME is not defined"
+#define CONFIGURE_NETWORK_DRIVER_NAME "no_network1"
+#endif
+
+#if !defined(CONFIGURE_NETWORK_DRIVER_ATTACH)
+#warning "CONFIGURE_NETWORK_DRIVER_ATTACH is not defined"
+#define CONFIGURE_NETWORK_DRIVER_ATTACH 0
+#endif
+
+#if !defined(CONFIGURE_NETWORK_HOSTNAME)
+#define CONFIGURE_NETWORK_HOSTNAME "rtemstst"
+#endif
+
+#if !defined(CONFIGURE_NETWORK_DOMAINNAME)
+#define CONFIGURE_NETWORK_DOMAINNAME "nodomain.com"
+#endif
+
+#if !defined(CONFIGURE_NETWORK_IPADDR)
+#define CONFIGURE_NETWORK_IPADDR "10.10.10.10"
+#endif
+
+#if !defined(CONFIGURE_NETWORK_NETMASK)
+#define CONFIGURE_NETWORK_NETMASK "255.255.255.0"
+#endif
+
+#if !defined(CONFIGURE_NETWORK_GATEWAY)
+#define CONFIGURE_NETWORK_GATEWAY "10.10.10.1"
+#endif
+
+#if !defined(CONFIGURE_NETWORK_LOGHOST)
+#define CONFIGURE_NETWORK_LOGHOST CONFIGURE_NETWORK_GATEWAY
+#endif
+
+#if !defined(CONFIGURE_NETWORK_DNS)
+#define CONFIGURE_NETWORK_DNS CONFIGURE_NETWORK_GATEWAY
+#endif
+
+#if !defined(CONFIGURE_NETWORK_NTP)
+#define CONFIGURE_NETWORK_NTP CONFIGURE_NETWORK_GATEWAY
+#endif
+
+#include <bsp.h>
+
+/*
+ * Define RTEMS_SET_ETHERNET_ADDRESS if you want to specify the
+ * Ethernet address here. If RTEMS_SET_ETHERNET_ADDRESS is not
+ * defined the driver will choose an address.
+ */
+#if defined(CONFIGURE_ETHERNET_ADDRESS)
+static char ethernet_address[6] = { CONFIGURE_ETHERNET_ADDRESS };
+#endif
+
+#ifdef CONFIGURE_NETWORK_LOOPBACK
+/*
+ * Loopback interface
+ */
+extern void rtems_bsdnet_loopattach();
+static struct rtems_bsdnet_ifconfig loopback_config = {
+ "lo0", /* name */
+ rtems_bsdnet_loopattach, /* attach function */
+ NULL, /* link to next interface */
+ "127.0.0.1", /* IP address */
+ "255.0.0.0", /* IP net mask */
+};
+#endif
+
+/*
+ * Default network interface
+ */
+static struct rtems_bsdnet_ifconfig netdriver_config = {
+ CONFIGURE_NETWORK_DRIVER_NAME, /* name */
+ CONFIGURE_NETWORK_DRIVER_ATTACH, /* attach function */
+#ifdef CONFIGURE_NETWORK_LOOPBACK
+ &loopback_config, /* link to next interface */
+#else
+ NULL, /* No more interfaces */
+#endif
+
+#if defined (CONFIGURE_NETWORK_BOOTP) || defined (CONFIGURE_NETWORK_DHCP)
+ NULL, /* BOOTP/DHCP supplies IP address */
+ NULL, /* BOOTP/DHCP supplies IP net mask */
+#else
+ CONFIGURE_NETWORK_IPADDR, /* IP address */
+ CONFIGURE_NETWORK_NETMASK, /* IP net mask */
+#endif /* !CONFIGURE_NETWORK_BOOTP */
+
+#if (defined (CONFIGURE_ETHERNET_ADDRESS))
+ ethernet_address, /* Ethernet hardware address */
+#else
+ NULL, /* Driver supplies hardware address */
+#endif
+ 0 /* Use default driver parameters */
+};
+
+/*
+ * Network configuration
+ */
+struct rtems_bsdnet_config rtems_bsdnet_config = {
+ &netdriver_config,
+
+#if (defined (CONFIGURE_NETWORK_BOOTP))
+ rtems_bsdnet_do_bootp,
+#elif (defined (CONFIGURE_NETWORK_DHCP))
+ rtems_bsdnet_do_dhcp,
+#else
+ NULL,
+#endif
+
+#if (defined (CONFIGURE_NETWORK_PRIORITY))
+ CONFIGURE_NETWORK_PRIORITY, /* Default network task priority */
+#else
+ 0, /* Default network task priority */
+#endif
+
+#if (defined (CONFIGURE_NETWORK_MBUFS))
+ CONFIGURE_NETWORK_MBUFS, /* Default mbuf capacity */
+#else
+ 0, /* Default mbuf capacity */
+#endif
+
+#if (defined (CONFIGURE_NETWORK_MCLUSTERS))
+ CONFIGURE_NETWORK_MCLUSTERS, /* Default mbuf cluster capacity */
+#else
+ 0, /* Default mbuf cluster capacity */
+#endif
+
+#if !defined (CONFIGURE_NETWORK_BOOTP)
+ CONFIGURE_NETWORK_HOSTNAME, /* Host name */
+#endif
+#if !defined (CONFIGURE_NETWORK_BOOTP) && !defined(CONFIGURE_NETWORK_DHCP)
+ CONFIGURE_NETWORK_DOMAINNAME, /* Domain name */
+ CONFIGURE_NETWORK_GATEWAY, /* Gateway */
+ CONFIGURE_NETWORK_LOGHOST, /* Log host */
+ { CONFIGURE_NETWORK_DNS }, /* Name server(s) */
+ { CONFIGURE_NETWORK_NTP }, /* NTP server(s) */
+#endif /* !CONFIGURE_NETWORK_BOOTP */
+};
+
+#endif /* _CONFIGURE_NETWORKCONFIG_H_ */
diff --git a/pc386-gdb.c b/pc386-gdb.c
new file mode 100644
index 0000000..08d5fe5
--- /dev/null
+++ b/pc386-gdb.c
@@ -0,0 +1,39 @@
+/*
+ * $Id$
+ *
+ * RTEMS Project (http://www.rtems.org/)
+ *
+ * Copyright 2007 Chris Johns (chrisj@rtems.org)
+ */
+
+/**
+ * PC386 GDB support.
+ */
+
+#include <stdio.h>
+
+#include <bsp.h>
+#include <uart.h>
+
+void
+pc386_gdb_init (void)
+{
+ printf ("GDB Initialisation\n");
+
+ i386_stub_glue_init (BSP_UART_COM2);
+
+ /*
+ * Init GDB stub itself
+ */
+ set_debug_traps();
+
+ /*
+ * Init GDB break in capability, has to be called after set_debug_traps
+ */
+ i386_stub_glue_init_breakin();
+
+ /*
+ * Put breakpoint in and stop and wait for GDB.
+ */
+ breakpoint();
+}
diff --git a/pc386-gdb.h b/pc386-gdb.h
new file mode 100644
index 0000000..4b93591
--- /dev/null
+++ b/pc386-gdb.h
@@ -0,0 +1,18 @@
+/*
+ * $Id$
+ *
+ * RTEMS Project (http://www.rtems.org/)
+ *
+ * Copyright 2007 Chris Johns (chrisj@rtems.org)
+ */
+
+/**
+ * PC386 GDB support.
+ */
+
+#if !defined (_PC386_GDB_H_)
+#define _PC386_GDB_H_
+
+void pc386_gdb_init (void);
+
+#endif
diff --git a/pc586-gdbinit-script b/pc586-gdbinit-script
new file mode 100644
index 0000000..6baf230
--- /dev/null
+++ b/pc586-gdbinit-script
@@ -0,0 +1,12 @@
+define rrb
+ set $pc=bsp_reset
+ c
+end
+#set remotebaud 115200
+#target remote /dev/ttyUSB0
+target remote :1234
+b rtems_fatal_error_occurred
+#source /opt/work/sw/rtems/src/rtems-gdb-macros
+#finish
+#finish
+#next
diff --git a/pkgconfig.py b/pkgconfig.py
new file mode 100644
index 0000000..3e14574
--- /dev/null
+++ b/pkgconfig.py
@@ -0,0 +1,79 @@
+#
+# Pkg-config in python. Pkg-config as a tool is a good idea how-ever the
+# implementation is really Linux (or Unix) based and requires a couple of
+# packages that it should not. If it was implemented with all parts included it
+# would be portable and I suspect useful to others on platforms other than
+# Linux or Unix equivs that contain the required packages.
+#
+import re
+
+class error(Exception):
+ def __init__(self, msg):
+ self.msg = msg
+
+ def __str__(self):
+ return self.msg
+
+class package:
+ def __init__(self, file = None):
+ self.defines = {}
+ self.fields = {}
+ if file:
+ self.load(file)
+
+ def load(self, file):
+ f = open(file)
+ tm = False
+ for l in f.readlines():
+ l = l[:-1]
+ hash = l.find('#')
+ if hash >= 0:
+ l = l[:hash]
+ if len(l):
+ d = 0
+ define = False
+ eq = l.find('=')
+ dd = l.find(':')
+ if eq > 0 and dd > 0:
+ if eq < dd:
+ define = True
+ d = eq
+ else:
+ define = False
+ d = dd
+ elif eq >= 0:
+ define = True
+ d = eq
+ elif dd >= 0:
+ define = False
+ d = dd
+ if d > 0:
+ lhs = l[:d].lower()
+ rhs = l[d + 1:]
+
+ if tm:
+ print('define: ' + str(define) + ', lhs: ' + lhs + ', ' + rhs)
+
+ if define:
+ self.defines[lhs] = rhs
+ else:
+ self.fields[lhs] = rhs
+
+ def get(self, label):
+ if label.lower() not in self.fields:
+ raise error('Label not found: ' + label)
+ mre = re.compile('\$\{[^\}]+\}')
+ s = self.fields[label.lower()]
+ expanded = True
+ tm = False
+ while expanded:
+ expanded = False
+ if tm:
+ print 'pc:get: "' + s + '"'
+ ms = mre.findall(s)
+ for m in ms:
+ mn = m[2:-1]
+ if mn.lower() in self.defines:
+ s = s.replace(m, self.defines[mn.lower()])
+ expanded = True
+ return s
diff --git a/pkgconfig.pyc b/pkgconfig.pyc
new file mode 100644
index 0000000..1883af6
--- /dev/null
+++ b/pkgconfig.pyc
Binary files differ
diff --git a/rtems-grub-h0-1.cfg b/rtems-grub-h0-1.cfg
new file mode 100755
index 0000000..3438d63
--- /dev/null
+++ b/rtems-grub-h0-1.cfg
@@ -0,0 +1,9 @@
+# RTEMS Grub configuration for RTEMS Testing
+set default=0
+timeout=0
+
+menuentry "RTEMS RTL Tester" {
+ set root=(hd0,1)
+ multiboot (hd0,1)/rtld --console=com1 --ide=0
+}
+
diff --git a/rtems-rtl.txt b/rtems-rtl.txt
new file mode 100644
index 0000000..80645cd
--- /dev/null
+++ b/rtems-rtl.txt
@@ -0,0 +1,310 @@
+RTEMS Runtime Link Editor (RTL)
+===============================
+Chris Johns <chrisj@rtems.org>
+1.0, Decemeber 2011
+:doctype: book
+:toc:
+:icons:
+:numbered:
+
+image:images/rtemswhitebg.jpg["RTEMS",width="40%"]
+
+Background
+----------
+
+This project adds support for the 'dlopen', 'dlclose' and 'dlsym' calls as
+defined in the POSIX and related standards to the RTEMS operating system.
+
+This test harness contains a new runtime linker as well as the Android and
+NetBSD RTLD code. This support will go away so check earlier snapshots to find
+that support. Neither the Android or NetBSD code is being directly used in this
+project and only serves as a reference.
+
+The project built and tested the NetBSD code to look into using dynamic ELF
+object files as a means of runtime loading code into RTEMS. Dynamic object
+files are used by ELF based operating systems to share libraries and support
+this function well. This model of dynamic loading does not map to RTEMS with
+the same benefits. Simply put, RTEMS is not a multi-process environment nor
+does it use memory protection or partitioned memory systems to create a virtual
+process environment and this is where the benefits of using dynamic object
+file's appear. Shared libraries allow code to be shared amongst a number of
+processes operating in different virtual address spaces and while these
+processes may share code they are kept separate for security reasons. Dynamic
+ELF files provide the following characteristics to support sharing:
+
+. Procedure Lookup Tables (PLT)
+. Global Offset Tables (GOT)
+. Position Independent Code (PIC)
+. Whole file memory footprint
+
+The PLT and GOT tables along with PIC code provide a small contained way to
+locate a dynamic object file without the dynamic object file requiring
+relocation fixups all through itself. This is important on shared library
+system as it avoids the need for each process having a private copy of the
+shared library code which defeats the purpose of sharing increasing the memory
+usage across the system. On a shared library system the whole object file is
+mapped into the process's address space and demand loading manages the physical
+memory used by the process. If a process modifies a part of the shared library
+the 'copy on write' or COW features of the operating system takes a copy of
+that page of memory and makes it private to that process. With a shared library
+made up of dynamic object files This happens when the process writes to a data
+variable that is part of the shared library or the code is modified. To
+minimise possible changes execution within the shared library is realtive using
+position independent code (PIC) and calls externally are made using the PLT
+tables which are altered to match the shared code's address mapping. The PTL
+tables are small relative to the size of a shared library.
+
+The downside of this design is the performance overhead the indirect procedure
+and data references incur plus the need to load the whole object file image
+into memory. On a multi-process system with virtual memory demand paging these
+negatives are minor compared to the positives, how-ever on RTEMS, a single
+process system without virtual memory there are no positives only negatives.
+
+The NetBSD code was used to attempt to get relocatable code into a dynamic ELF
+file. The tools for RTEMS would not do this. Relocatable code can be found in
+relocatable type ELF file. The NetBSD loader checks for any ELF file that is
+not dynamic returning an error. This means this code base could not be used
+without major changes. The NetBSD code does support a large number of
+architectures and has relocation support.
+
+The Android code also only supports dynamic modules and its code base only
+supports a few targets and this support is not as cleanly implemented as
+NetBSD.
+
+<<<<
+RTEMS Runtime Link Editor
+-------------------------
+
+The RTL code contained in this project is new code developed for RTEMS using
+the features of RTEMS to give a small tight implementation. It supports the
+loading of relocatable object files, invoking of contructor and destructor
+functions, global symbol relocation and loading directly from archive format
+files. The header files provide documentation about the functions provided and
+the main.c file shows the command added to support development.
+
+The target code is supported by a host RTEMS specific linker called
+'rtems-ld'. The RTEMS linker is contained in a separate package.
+
+Build System
+~~~~~~~~~~~~
+
+The package uses the waf build system. You can find waf here:
+
+ http://waf.googlecode.com/
+
+Waf is a fast full featured build environment that removes the need for make,
+make files or any other traditional build system infrastructure. For details
+please refer to the WAF-README file. It can be used to build any RTEMS project.
+
+Follow the download instructions for waf and install into your path. If you are
+on Windows you will need to download a recent 2.7 or later version of Python
+and add to the global path.
+
+Testing
+-------
+
+The development is using the HEAD branch of RTEMS and the BSP is the Sparc
+Instruction Simulator. Other architectures are support and if you have tools
+and BSPs installed. The build scripts will attempt to detect them and build for
+them. If there is no support for a specific architecture just copy the empty
+NIOS2 file to the missing architecture.
+
+To build:
+
+. Get the latest tools.
+. Check out RTEMS from CVS and run a bootstrap.
+. Build using:
++
+-------------------------------------------------------------
+$RTEMS_SRC/configure --target=sparc-rtems4.11 \ <1>
+ --prefix=$RTEMS_TEST_PREFIX/build/4.11 \ <2>
+ --enable-rtemsbsp=sis \
+ --enable-tests=samples \
+ --enable-cxx \
+ --enable-maintainer-mode \
+ --enable-rtems-debug
+-------------------------------------------------------------
+
+<1> $RTEMS_SRC is the path to the RTEMS source code.
+<2> $RTEMS_TEST_PREFIX is the path you install your test RTEMS builds.
+
+. Configure this package change directory to the source code and then:
++
+-------------------------------------------------------------
+waf configure --rtems=/opt/work/rtems/build/4.11 \
+ --rtems-tools=/opt/work/rtems/4.11,/opt/work/rtems/nios/nios2-rtems-11.0
+-------------------------------------------------------------
++
+You can also use:
++
+-------------------------------------------------------------
+waf --help
+-------------------------------------------------------------
++
+to get a list of options. The RTEMS specific ones are:
++
+--rtems=RTEMS_PATH:: Path to an installed RTEMS BSPs.
++
+--rtems-tools=RTEMS_TOOLS:: Path to RTEMS tools. This options avoids the need
+to have the tools in your shell path.
++
+--rtems-version=RTEMS_VERSION:: RTEMS version (default 4.11). This is only
+needed if you are not using the default.
++
+--rtems-archs=RTEMS_ARCHS:: List of RTEMS architectures to build. By default
+all architectures detected when configuring are built.
++
+--rtems-bsps=RTEMS_BSPS:: List of BSPs to build. This lets you specify a
+specific set of BSPs to build for. By default all BSPs are built.
++
+--show-commands:: Print the commands as strings. This will display the full
+command used. This can help when debugging tool related issues.
+
+. Build the RTL test application do:
++
+-------------------------------------------------------------
+waf
+-------------------------------------------------------------
+
+. Run in the GDB SIS simulator:
++
+-------------------------------------------------------------
+sparc-rtems4.11-run build/sparc-rtems4.11-sis/rtld
+-------------------------------------------------------------
+
+RTEMS Linker
+------------
+
+The loading of relocatable object files allows the memory map to be determined
+at run time giving us the maximum flexibility because the user does not need to
+manage the memory. This approach how-ever requires loading be managed at the
+object file level and this means there will be unresolved symbols and these
+symbols can be from any library referenced by the project.
+
+The target link editor can resolve these symbols as it loads object files if
+given a list of object files. A linker typically generates this list by loading
+the symbol tables of the referenced librarys and then selecting the object
+files referenced. The target does not have access to the librarys nor does it
+typically have the memory and performance needed to manage large symbol tables.
+
+To resolve this an RTEMS linker has been developed. This is a C++ host only
+program that can read and access the ELF files, load the symbols tables and
+resolve the external symbols. It has a typical linker command line and outputs
+a list of dependent object files or an archive file containting all referenced
+object files. You can provide the linker with the base image and only the
+object files not present are included. The base image is the static RTEMS image
+you boot on your target hardware.
+
+This approach over comes the "library dependence" problem present in embedded
+systems that use cross-compilation and standards linkers. If you have a
+statically linked base image containing code from a library and you wish to
+create a run time loadable image, either statically or incrementally linked
+using code from the same library you do not know if code from the library is
+present or not. If you feed the linker the base image's symbols and library the
+linker will generate errors for duplicant symbols in the base image from the
+same library. If you do not provide the library the linker will generate
+unresolved symbol errors. We need a special linker that can handle this and
+understand the role of the base image and the libraries present.
+
+Run Loadable Models
+~~~~~~~~~~~~~~~~~~~
+
+There are a number of possible application models users may wish to use. A
+project may decide to vary the model used depending on the phase the project is
+in.
+
+Script::
+
+Load the application from the object files in the application and the
+libraries. The target needs to have access to all libraries and this typically
+means networked file system (NFS) access to the development host containing the
+libraries being used. With a suitable initialisation mounting the network disk
+and libraries paths being set an application can be loaded using a script of
+files. The approach gives the developer flexiblity to update and play with
+various parts of the code as they go.
+
+Single Image::
+
+The RTEMS linker creates a single image of the application by pulling in the
+object files from the libraries used by the application. The linker can be
+given the base image and will link against the symbols it contains. This means
+the base image and an application can use the same library and the application
+will only contain the code from the library it needs. If at the point of
+loading the object file has been loaded from another application the one
+included in this application will not be loaded.
+
+For those users who need a determinisitic layout the loader should load the
+same object files in the same place each time. This is deterministic.
+
+Status
+------
+
+The current status is loading is:
+
+. Loading of an object file as a file or within a archive works on the Sparc,
+i386 and m68k architectures. Other architectures are present how-ever testing
+may be limited. The NIOS file is an empty template to allow the package to
+build.
+
+. Shell commands +dlopen+ ('dlo'), +dlclose+ ('dlc'), +dlsearch+ ('dls'), and
+execute (+dlx+) provide a way to test the loader.
+
+. Shell access to the loader is provided via the 'rtl' command. The command
+provdes:
++
+. status:: The status of the loader.
++
+. list:: List of loaded object modules.
++
+. sym:: Symbol table access.
++
+. obj:: Object file details.
+
+. The RTEMS linker and loader need a simple way to have a single application
+archive loaded and run. This could be a script in a special section of the
+archive, an elf file or something else.
+
+Development Tasks
+~~~~~~~~~~~~~~~~~
+
+. Add the ability to hold unresolved externals an object module may have once
+loaded. We need the ability to load object modules with unresolved externals
+because object modules may depend on eac other.
+
+This is complex issue due to the memory management issues it creates. Holding
+the unresolved externals and then releasing them later will fragment the
+heap. The proper solution is to add a memory manager and allocator to the
+loader. This would be used for all symbol allocations.
+
+The other solution is to not allow loading of object modules with unresolved
+symbols and to force application that have them to incrementally link. The
+issue is here is 3rd party libraries and that makes this solution less than
+ideal.
+
+. Add an application loader. An application needs to be formally
+defined. Currently the RTEMS linker creates a standard library archive. A
+application format needs some extra information. This could be as simple as
+something that indicates this is an RTEMS application, through to the entry
+point and a load order for the object modules in the archive to avoid
+unresolved externals.
+
+. Place the code into the RTEMS source tree.
+
+Development Cut-n-Pastes for Chris
+----------------------------------
+
+Note: the '--' is required to abort getopt processing in sis-gdb
+
+-------------------------------------------------------------
+waf configure --rtems=/Users/chris/Development/rtems/build/4.11 \
+--rtems-tools=/Users/chris/Development/rtems/4.11,/Users/chris/Development/rtems/nios/gnu/nios2-rtems-11.0
+~/Development/rtems/build/testing/sim-scripts/sis-gdb -- \
+--annotate=3 /Users/chris/Development/rtems/build/rtl/sparc/rtld
+-------------------------------------------------------------
+
+-------------------------------------------------------------
+sparc-rtems4.11-readelf -all x-long-name-to-create-gnu-extension-in-archive.o | less
+~/Development/rtems/build/testing/sim-scripts/sis -l 10 \
+$(find sparc-rtems4.11/c/sis/testsuites/psxtests -name \*.exe) > results-no-oe-align
+/Users/chris/Development/rtems/build/newlib/newlib-1.18.0/newlib/libc
+-------------------------------------------------------------
diff --git a/rtems.py b/rtems.py
new file mode 100644
index 0000000..a98e433
--- /dev/null
+++ b/rtems.py
@@ -0,0 +1,392 @@
+#
+# RTEMS support for applications.
+#
+# Copyright Chris Johns (chrisj@rtems.org)
+#
+import os
+import os.path
+import pkgconfig
+import subprocess
+
+default_version = '4.11'
+default_label = 'rtems-' + default_version
+default_path = '/opt/' + default_label
+
+def options(opt):
+ opt.add_option('--rtems',
+ default = default_path,
+ dest = 'rtems_path',
+ help = 'Path to an installed RTEMS.')
+ opt.add_option('--rtems-tools',
+ default = None,
+ dest = 'rtems_tools',
+ help = 'Path to RTEMS tools.')
+ opt.add_option('--rtems-version',
+ default = default_version,
+ dest = 'rtems_version',
+ help = 'RTEMS version (default ' + default_version + ').')
+ opt.add_option('--rtems-archs',
+ default = 'all',
+ dest = 'rtems_archs',
+ help = 'List of RTEMS architectures to build.')
+ opt.add_option('--rtems-bsps',
+ default = 'all',
+ dest = 'rtems_bsps',
+ help = 'List of BSPs to build.')
+ opt.add_option('--show-commands',
+ action = 'store_true',
+ default = False,
+ dest = 'show_commands',
+ help = 'Print the commands as strings.')
+
+def init(ctx):
+ try:
+ import waflib.Options
+ import waflib.ConfigSet
+
+ #
+ # Load the configuation set from the lock file.
+ #
+ env = waflib.ConfigSet.ConfigSet()
+ env.load(waflib.Options.lockfile)
+
+ #
+ # Check the tools, architectures and bsps.
+ #
+ rtems_tools, archs, arch_bsps = check_options(ctx,
+ env.options['rtems_tools'],
+ env.options['rtems_path'],
+ env.options['rtems_version'],
+ env.options['rtems_archs'],
+ env.options['rtems_bsps'])
+
+ #
+ # Update the contextes for all the bsps.
+ #
+ from waflib.Build import BuildContext, CleanContext, \
+ InstallContext, UninstallContext
+ for x in arch_bsps:
+ for y in (BuildContext, CleanContext, InstallContext, UninstallContext):
+ name = y.__name__.replace('Context','').lower()
+ class context(y):
+ cmd = name + '-' + x
+ variant = x
+
+ #
+ # Add the various commands.
+ #
+ for cmd in ['build', 'clean']:
+ if cmd in waflib.Options.commands:
+ waflib.Options.commands.remove(cmd)
+ for x in arch_bsps:
+ waflib.Options.commands.insert(0, cmd + '-' + x)
+ except:
+ pass
+
+def configure(conf):
+ #
+ # Handle the show commands option.
+ #
+ if conf.options.show_commands:
+ show_commands = 'yes'
+ else:
+ show_commands = 'no'
+
+ rtems_tools, archs, arch_bsps = check_options(conf,
+ conf.options.rtems_tools,
+ conf.options.rtems_path,
+ conf.options.rtems_version,
+ conf.options.rtems_archs,
+ conf.options.rtems_bsps)
+
+ _log_header(conf)
+ conf.to_log('Architectures: ' + ','.join(archs))
+
+ tools = _find_tools(conf, archs, rtems_tools)
+
+ for ab in arch_bsps:
+ env = conf.env.copy()
+ env.set_variant(ab)
+ conf.set_env_name(ab, env)
+ conf.setenv(ab)
+
+ arch = _arch_from_arch_bsp(ab)
+
+ conf.env.RTEMS_PATH = conf.options.rtems_path
+ conf.env.RTEMS_VERSION = conf.options.rtems_version
+ conf.env.RTEMS_ARCH_BSP = ab
+ conf.env.RTEMS_ARCH = arch.split('-')[0]
+ conf.env.RTEMS_ARCH_RTEMS = arch
+ conf.env.RTEMS_BSP = _bsp_from_arch_bsp(ab)
+
+ for t in tools[arch]:
+ conf.env[t] = tools[arch][t]
+
+ conf.load('gcc')
+ conf.load('g++')
+ conf.load('gas')
+
+ flags = _load_flags(conf, ab, conf.options.rtems_path)
+
+ conf.env.CFLAGS = flags['CFLAGS']
+ conf.env.LINKFLAGS = flags['CFLAGS'] + flags['LDFLAGS']
+ conf.env.LIB = flags['LIB']
+
+ #
+ # Hack to work around NIOS2 naming.
+ #
+ if conf.env.RTEMS_ARCH in ['nios2']:
+ objcopy_format = 'elf32-little' + conf.env.RTEMS_ARCH
+ else:
+ objcopy_format = 'elf32-' + conf.env.RTEMS_ARCH
+
+ conf.env.OBJCOPY_FLAGS = ['-O ', objcopy_format]
+
+ conf.env.SHOW_COMMANDS = show_commands
+
+ conf.setenv('')
+
+ conf.env.RTEMS_TOOLS = rtems_tools
+ conf.env.ARCHS = archs
+ conf.env.ARCH_BSPS = arch_bsps
+
+ conf.env.SHOW_COMMANDS = show_commands
+
+def build(bld):
+ if bld.env.SHOW_COMMANDS == 'yes':
+ output_command_line()
+
+def check_options(ctx, rtems_tools, rtems_path, rtems_version, rtems_archs, rtems_bsps):
+ #
+ # Check the paths are valid.
+ #
+ if not os.path.exists(rtems_path):
+ ctx.fatal('RTEMS path not found.')
+ if os.path.exists(os.path.join(rtems_path, 'lib', 'pkgconfig')):
+ rtems_config = None
+ elif os.path.exists(os.path.join(rtems_path, 'rtems-config')):
+ rtems_config = os.path.join(rtems_path, 'rtems-config')
+ else:
+ ctx.fatal('RTEMS path is not valid. No lib/pkgconfig or rtems-config found.')
+
+ #
+ # We can more than one path to tools. This happens when testing different
+ # versions.
+ #
+ if rtems_tools is not None:
+ rt = rtems_tools.split(',')
+ tools = []
+ for path in rt:
+ if not os.path.exists(path):
+ ctx.fatal('RTEMS tools path not found: ' + path)
+ if not os.path.exists(os.path.join(path, 'bin')):
+ ctx.fatal('RTEMS tools path does not contain a \'bin\' directory: ' + path)
+ tools += [os.path.join(path, 'bin')]
+ else:
+ tools = None
+
+ #
+ # Match the archs requested against the ones found. If the user
+ # wants all (default) set all used.
+ #
+ if rtems_archs == 'all':
+ archs = _find_installed_archs(rtems_config, rtems_path, rtems_version)
+ else:
+ archs = _check_archs(rtems_config, rtems_archs, rtems_path, rtems_version)
+
+ if len(archs) == 0:
+ ctx.fatal('Could not find any architectures')
+
+ #
+ # Get the list of valid BSPs. This process filters the architectures
+ # to those referenced by the BSPs.
+ #
+ if rtems_bsps == 'all':
+ arch_bsps = _find_installed_arch_bsps(rtems_config, rtems_path, archs)
+ else:
+ arch_bsps = _check_arch_bsps(rtems_config, rtems_bsps, rtems_path, archs)
+
+ return tools, archs, arch_bsps
+
+def arch(arch_bsp):
+ return _arch_from_arch_bsp(arch_bsp).split('-')[0]
+
+def bsp(arch_bsp):
+ return _bsp_from_arch_bsp(arch_bsp)
+
+def arch_bsps(ctx):
+ return ctx.env.ARCH_BSPS
+
+def arch_bsp_env(ctx, arch_bsp):
+ return ctx.env_of_name(arch_bsp).derive()
+
+def clone_tasks(bld):
+ if bld.cmd == 'build':
+ for obj in bld.all_task_gen[:]:
+ for x in arch_bsp:
+ cloned_obj = obj.clone(x)
+ kind = Options.options.build_kind
+ if kind.find(x) < 0:
+ cloned_obj.posted = True
+ obj.posted = True
+
+#
+# From the demos. Use this to get the command to cut+paste to play.
+#
+def output_command_line():
+ # first, display strings, people like them
+ from waflib import Utils, Logs
+ from waflib.Context import Context
+ def exec_command(self, cmd, **kw):
+ subprocess = Utils.subprocess
+ kw['shell'] = isinstance(cmd, str)
+ if isinstance(cmd, str):
+ Logs.info('%s' % cmd)
+ else:
+ Logs.info('%s' % ' '.join(cmd)) # here is the change
+ Logs.debug('runner_env: kw=%s' % kw)
+ try:
+ if self.logger:
+ self.logger.info(cmd)
+ kw['stdout'] = kw['stderr'] = subprocess.PIPE
+ p = subprocess.Popen(cmd, **kw)
+ (out, err) = p.communicate()
+ if out:
+ self.logger.debug('out: %s' % out.decode(sys.stdout.encoding or 'iso8859-1'))
+ if err:
+ self.logger.error('err: %s' % err.decode(sys.stdout.encoding or 'iso8859-1'))
+ return p.returncode
+ else:
+ p = subprocess.Popen(cmd, **kw)
+ return p.wait()
+ except OSError:
+ return -1
+ Context.exec_command = exec_command
+
+ # Change the outputs for tasks too
+ from waflib.Task import Task
+ def display(self):
+ return '' # no output on empty strings
+
+ Task.__str__ = display
+
+def _find_tools(conf, archs, paths):
+ tools = {}
+ for arch in archs:
+ arch_tools = {}
+ arch_tools['CC'] = conf.find_program([arch + '-gcc'], path_list = paths)
+ arch_tools['CXX'] = conf.find_program([arch + '-g++'], path_list = paths)
+ arch_tools['AS'] = conf.find_program([arch + '-gcc'], path_list = paths)
+ arch_tools['LD'] = conf.find_program([arch + '-ld'], path_list = paths)
+ arch_tools['AR'] = conf.find_program([arch + '-ar'], path_list = paths)
+ arch_tools['LINK_CC'] = arch_tools['CC']
+ arch_tools['LINK_CXX'] = arch_tools['CXX']
+ arch_tools['AR'] = conf.find_program([arch + '-ar'], path_list = paths)
+ arch_tools['LD'] = conf.find_program([arch + '-ld'], path_list = paths)
+ arch_tools['NM'] = conf.find_program([arch + '-nm'], path_list = paths)
+ arch_tools['OBJDUMP'] = conf.find_program([arch + '-objdump'], path_list = paths)
+ arch_tools['OBJCOPY'] = conf.find_program([arch + '-objcopy'], path_list = paths)
+ arch_tools['READELF'] = conf.find_program([arch + '-readelf'], path_list = paths)
+ tools[arch] = arch_tools
+ return tools
+
+def _find_installed_archs(config, path, version):
+ archs = []
+ if config is None:
+ for d in os.listdir(path):
+ if d.endswith('-rtems' + version):
+ archs += [d]
+ else:
+ a = subprocess.check_output([config, '--list-format', '"%(arch)s"'])
+ a = a[:-1].replace('"', '')
+ archs = a.split()
+ archs = ['%s-rtems4.11' %(x) for x in archs]
+ archs.sort()
+ return archs
+
+def _check_archs(config, req, path, version):
+ installed = _find_all_archs(config, path, version)
+ archs = []
+ for a in req.split(','):
+ arch = a + '-rtems' + version
+ if arch in installed:
+ archs += [arch]
+ archs.sort()
+ return archs
+
+def _find_installed_arch_bsps(config, path, archs):
+ arch_bsps = []
+ if config is None:
+ for f in os.listdir(_pkgconfig_path(path)):
+ if f.endswith('.pc'):
+ if _arch_from_arch_bsp(f[:-3]) in archs:
+ arch_bsps += [f[:-3]]
+ else:
+ ab = subprocess.check_output([config, '--list-format'])
+ ab = ab[:-1].replace('"', '')
+ ab = ab.replace('/', '-rtems4.11-')
+ arch_bsps = ab.split()
+ arch_bsps.sort()
+ return arch_bsps
+
+def _check_arch_bsps(req, path, archs):
+ installed = _find_installed_bsps(path, archs)
+ bsps = []
+ for b in req.split(','):
+ if b in installed:
+ bsps += [b]
+ bsps.sort()
+ return bsps
+
+def _arch_from_arch_bsp(arch_bsp):
+ return '-'.join(arch_bsp.split('-')[:2])
+
+def _bsp_from_arch_bsp(arch_bsp):
+ return '-'.join(arch_bsp.split('-')[2:])
+
+def _pkgconfig_path(path):
+ return os.path.join(path, 'lib', 'pkgconfig')
+
+def _load_flags(conf, arch_bsp, path):
+ if not os.path.exists(path):
+ ctx.fatal('RTEMS path not found.')
+ if os.path.exists(_pkgconfig_path(path)):
+ pc = os.path.join(_pkgconfig_path(path), arch_bsp + '.pc')
+ conf.to_log('Opening and load pkgconfig: ' + pc)
+ pkg = pkgconfig.package(pc)
+ config = None
+ elif os.path.exists(os.path.join(path, 'rtems-config')):
+ config = os.path.join(path, 'rtems-config')
+ pkg = None
+ flags = {}
+ _log_header(conf)
+ flags['CFLAGS'] = _load_flags_set('CFLAGS', arch_bsp, conf, config, pkg)
+ flags['LDFLAGS'] = _load_flags_set('LDFLAGS', arch_bsp, conf, config, pkg)
+ flags['LIB'] = _load_flags_set('LIB', arch_bsp, conf, config, pkg)
+ return flags
+
+def _load_flags_set(flags, arch_bsp, conf, config, pkg):
+ conf.to_log('%s ->' % flags)
+ if pkg is not None:
+ try:
+ flagstr = pkg.get(flags)
+ except pkgconfig.error as e:
+ conf.to_log('pkconfig warning: ' + e.msg)
+ conf.to_log(' ' + flagstr)
+ else:
+ flags_map = { 'CFLAGS': '--cflags',
+ 'LDFLAGS': '--ldflags',
+ 'LIB': '--libs' }
+ ab = arch_bsp.split('-')
+ #conf.check_cfg(path = config,
+ # package = '',
+ # uselib_store = 'rtems',
+ # args = '--bsp %s/%s %s' % (ab[0], ab[2], flags_map[flags]))
+ #print conf.env
+ #print '%r' % conf
+ #flagstr = '-l -c'
+ flagstr = subprocess.check_output([config, '--bsp', '%s/%s' % (ab[0], ab[2]), flags_map[flags]])
+ return flagstr.split()
+
+def _log_header(conf):
+ conf.to_log('-----------------------------------------')
diff --git a/rtl-chain-iterator.c b/rtl-chain-iterator.c
new file mode 100644
index 0000000..414b4ba
--- /dev/null
+++ b/rtl-chain-iterator.c
@@ -0,0 +1,59 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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/rtl-chain-iterator.h b/rtl-chain-iterator.h
new file mode 100644
index 0000000..bdaa90e
--- /dev/null
+++ b/rtl-chain-iterator.h
@@ -0,0 +1,61 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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/rtl-debugger.c b/rtl-debugger.c
new file mode 100644
index 0000000..d6360ef
--- /dev/null
+++ b/rtl-debugger.c
@@ -0,0 +1,41 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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 <link.h>
+
+struct r_debug _rtld_debug;
+
+void
+_rtld_debug_state (void)
+{
+ /*
+ * Empty. GDB only needs to hit this location.
+ */
+}
diff --git a/rtl-elf.c b/rtl-elf.c
new file mode 100644
index 0000000..7ef8104
--- /dev/null
+++ b/rtl-elf.c
@@ -0,0 +1,605 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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 <rtl.h>
+#include "rtl-elf.h"
+#include "rtl-error.h"
+#include "rtl-trace.h"
+
+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;
+ int unresolved;
+
+ /*
+ * 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 ("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);
+
+ unresolved = 0;
+
+ 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;
+ 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.
+ */
+ 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))
+ {
+ ++unresolved;
+ relocate = false;
+ }
+ }
+
+ if (relocate)
+ {
+ if (is_rela)
+ {
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf ("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 (obj, rela, targetsect, symvalue))
+ return false;
+ }
+ else
+ {
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf ("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 (obj, rel, targetsect, symvalue))
+ return false;
+ }
+ }
+ }
+
+ /*
+ * Set the unresolved externals status if there are unresolved externals.
+ */
+ if (unresolved)
+ 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 = calloc (1, obj->global_size);
+ 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;
+ }
+ memcpy (string, name, strlen (name) + 1);
+ gsym->name = string;
+ string += strlen (name) + 1;
+ gsym->value = symbol.st_value + (uint8_t*) symsect->base;
+
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_SYMBOL))
+ printf ("sym:%-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;
+ }
+ }
+ }
+
+ 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 ("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_obj_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))
+ 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;
+
+ return true;
+}
+
diff --git a/rtl-elf.h b/rtl-elf.h
new file mode 100644
index 0000000..b6dc4a8
--- /dev/null
+++ b/rtl-elf.h
@@ -0,0 +1,129 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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 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 (rtems_rtl_obj_t* obj,
+ const Elf_Rel* rel,
+ rtems_rtl_obj_sect_t* sect,
+ 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 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 (rtems_rtl_obj_t* obj,
+ const Elf_Rela* rela,
+ rtems_rtl_obj_sect_t* sect,
+ 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);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/rtl-error.c b/rtl-error.c
new file mode 100644
index 0000000..cef6452
--- /dev/null
+++ b/rtl-error.c
@@ -0,0 +1,49 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @file
+ *
+ * @ingroup rtl
+ *
+ * @brief RTEMS Run-Time Linker Error
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <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/rtl-error.h b/rtl-error.h
new file mode 100644
index 0000000..0aaf24d
--- /dev/null
+++ b/rtl-error.h
@@ -0,0 +1,46 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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/rtl-fwd.h b/rtl-fwd.h
new file mode 100644
index 0000000..3527fca
--- /dev/null
+++ b/rtl-fwd.h
@@ -0,0 +1,35 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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/rtl-mdreloc-arm.c b/rtl-mdreloc-arm.c
new file mode 100644
index 0000000..8b210a2
--- /dev/null
+++ b/rtl-mdreloc-arm.c
@@ -0,0 +1,153 @@
+/*
+ * Taken from NetBSD and stripped of the relocations not needed on RTEMS.
+ *
+ * $Id$
+ */
+
+/* $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 <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));
+}
+
+bool
+rtems_rtl_elf_relocate_rela (rtems_rtl_obj_t* obj,
+ const Elf_Rela* rela,
+ rtems_rtl_obj_sect_t* sect,
+ const Elf_Sym* sym,
+ const char* symname)
+{
+ printf ("rtl: rela record not supported; please report\n");
+ return false;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (rtems_rtl_obj_t* obj,
+ const Elf_Rel* rel,
+ rtems_rtl_obj_sect_t* sect,
+ const Elf_Sym* sym,
+ const char* symname)
+{
+ Elf_Addr target = 0;
+ Elf_Addr* where;
+ Elf_Addr tmp;
+ Elf_Word symvalue;
+
+ where = (Elf_Addr *)(sect->base + rel->r_offset);
+
+ switch (ELF_R_TYPE(rel->r_info)) {
+ case R_TYPE(NONE):
+ break;
+
+ case R_TYPE(PC24): { /* word32 S - P + A */
+ Elf32_Sword addend;
+
+ /*
+ * Extract addend and sign-extend if needed.
+ */
+ addend = *where;
+ if (addend & 0x00800000)
+ addend |= 0xff000000;
+
+ if (!rtems_rtl_elf_find_symbol (obj, sym, symname, &symvalue))
+ return false;
+
+ tmp = (Elf_Addr) symvalue - (Elf_Addr) where + (addend << 2);
+ if ((tmp & 0xfe000000) != 0xfe000000 &&
+ (tmp & 0xfe000000) != 0) {
+ rtems_rtl_set_error ("%s: R_ARM_PC24 relocation @ %p to %s failed "
+ "(displacement %ld (%#lx) out of range)",
+ obj->oname, where, symname,
+ (long) tmp, (long) tmp);
+ return false;
+ }
+ tmp >>= 2;
+ *where = (*where & 0xff000000) | (tmp & 0x00ffffff);
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf ("rtl: reloc PC24 %s in %s --> %p @ %p\n",
+ symname, obj->oname, (void *)*where, where);
+ break;
+ }
+
+ case R_TYPE(ABS32): /* word32 B + S + A */
+ case R_TYPE(GLOB_DAT): /* word32 B + S */
+ if (!rtems_rtl_elf_find_symbol (obj, sym, symname, &symvalue))
+ return false;
+
+ if (__predict_true (RELOC_ALIGNED_P (where))) {
+ tmp = *where + symvalue;
+ /* Set the Thumb bit, if needed. */
+ if (ELF_ST_TYPE(def->st_info) == STT_ARM_TFUNC)
+ tmp |= 1;
+ *where = tmp;
+ } else {
+ tmp = load_ptr (where) + symvalue;
+ /* Set the Thumb bit, if needed. */
+ if (ELF_ST_TYPE(def->st_info) == STT_ARM_TFUNC)
+ tmp |= 1;
+ store_ptr (where, tmp);
+ }
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf ("rtl: reloc ABS32/GLOB_DAT %s in %s --> %p @ %p\n",
+ symname, obj->oname, (void *)tmp, where);
+ break;
+
+ case R_TYPE(RELATIVE): /* word32 B + A */
+ if (__predict_true (RELOC_ALIGNED_P (where))) {
+ tmp = *where + (Elf_Addr) sect->base;
+ *where = tmp;
+ } else {
+ tmp = load_ptr (where) + (Elf_Addr) sect->base;
+ store_ptr (where, tmp);
+ }
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf ("rtl: reloc RELATIVE in %s --> %p", obj->oname, (void *)tmp));
+ 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, symbol = %s\n",
+ ELF_R_SYM(rel->r_info), (uint32_t) ELF_R_TYPE(rel->r_info),
+ (void *)rel->r_offset, (void *)*where, symname);
+ 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/rtl-mdreloc-i386.c b/rtl-mdreloc-i386.c
new file mode 100644
index 0000000..472a246
--- /dev/null
+++ b/rtl-mdreloc-i386.c
@@ -0,0 +1,99 @@
+/*
+ * Taken from NetBSD and stripped of the relocations not needed on RTEMS.
+ *
+ * $Id$
+ */
+
+/* $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 <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)
+{
+ printf ("rtl: rela record not supported; please report\n");
+ return false;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (rtems_rtl_obj_t* obj,
+ const Elf_Rel* rel,
+ rtems_rtl_obj_sect_t* sect,
+ 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) in %s\n",
+ sect->name, (void*) symvalue,
+ (void *)*where, obj->oname);
+ 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 in %s\n",
+ sect->name, (void *)*where, obj->oname);
+ 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\n", obj->oname, (void *)*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/rtl-mdreloc-m68k.c b/rtl-mdreloc-m68k.c
new file mode 100644
index 0000000..fef380c
--- /dev/null
+++ b/rtl-mdreloc-m68k.c
@@ -0,0 +1,104 @@
+/*
+ * Taken from NetBSD and stripped of the relocations not needed on RTEMS.
+ *
+ * $Id$
+ */
+
+/* $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 <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)
+{
+ Elf_Addr target = 0;
+ Elf_Addr* where;
+
+ where = (Elf_Addr *)(sect->base + rela->r_offset);
+
+ switch (ELF_R_TYPE(rela->r_info)) {
+ case R_TYPE(NONE):
+ 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, obj->oname);
+ 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, obj->oname);
+ 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", obj->oname, (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 false;
+}
+
+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/rtl-mdreloc-nios2.c b/rtl-mdreloc-nios2.c
new file mode 100644
index 0000000..e96b3f6
--- /dev/null
+++ b/rtl-mdreloc-nios2.c
@@ -0,0 +1,46 @@
+/*
+ * Taken from NetBSD and stripped of the relocations not needed on RTEMS.
+ *
+ * $Id$
+ */
+
+/* $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 <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/rtl-mdreloc-powerpc.c b/rtl-mdreloc-powerpc.c
new file mode 100644
index 0000000..eb6c9b9
--- /dev/null
+++ b/rtl-mdreloc-powerpc.c
@@ -0,0 +1,155 @@
+/*
+ * Taken from NetBSD and stripped of the relocations not needed on RTEMS.
+ *
+ * $Id$
+ */
+
+/* $NetBSD: ppc_reloc.c,v 1.44 2010/01/13 20:17:22 christos Exp $ */
+
+/*-
+ * Copyright (C) 1998 Tsubai Masanari
+ * Portions copyright 2002 Charles M. Hannum <root@ihack.net>
+ * All rights reserved.
+ *
+ * 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <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)
+
+/*
+ * The PPC PLT format consists of three sections:
+ * (1) The "pltcall" and "pltresolve" glue code. This is always 18 words.
+ * (2) The code part of the PLT entries. There are 2 words per entry for
+ * up to 8192 entries, then 4 words per entry for any additional entries.
+ * (3) The data part of the PLT entries, comprising a jump table.
+ * This section is half the size of the second section (ie. 1 or 2 words
+ * per entry).
+ */
+
+/*
+ * Setup the plt glue routines.
+ */
+#define PLTCALL_SIZE 20
+#define PLTRESOLVE_SIZE 24
+
+bool
+rtems_rtl_elf_relocate_rela (rtems_rtl_obj_t* obj,
+ const Elf_Rela* rela,
+ rtems_rtl_obj_sect_t* sect,
+ const Elf_Sym* sym,
+ const char* symname)
+{
+ Elf_Addr target = 0;
+ Elf_Addr* where;
+ Elf_Word symvalue;
+
+ where = (Elf_Addr *)(sect->base + rela->r_offset);
+
+ switch (ELF_R_TYPE(rela->r_info)) {
+ case R_TYPE(JMP_SLOT):
+ case R_TYPE(NONE):
+ break;
+
+ case R_TYPE(PC32):
+ if (!rtems_rtl_elf_find_symbol (obj, sym, symname, &symvalue))
+ return false;
+
+ target = (Elf_Addr) symvalue + rela->r_addend;
+ *where += target - (Elf_Addr)where;
+
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf ("rtl: reloc PC32 %s in %s --> %p (%p) in %s\n",
+ symname, sect->name, (void*) (symvalue + rela->r_addend),
+ (void *)*where, obj->oname);
+ break;
+
+ case R_TYPE(32): /* word32 S + A */
+ case R_TYPE(GLOB_DAT): /* word32 S + A */
+ if (!rtems_rtl_elf_find_symbol (obj, sym, symname, &symvalue))
+ return false;
+
+ 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 %s in %s --> %p in %s\n",
+ symname, sect->name, (void *)*where, obj->oname);
+ break;
+
+ case R_TYPE(RELATIVE): /* word32 B + A */
+ *where += (Elf_Addr) sect->base + rela->r_addend;
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf ("rtl: reloc RELATIVE in %s --> %p\n", obj->oname, (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, symbol = %s\n",
+ ELF_R_SYM(rela->r_info), (uint32_t) ELF_R_TYPE(rela->r_info),
+ (void *)rela->r_offset, (void *)*where, symname);
+ 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 false;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (rtems_rtl_obj_t* obj,
+ const Elf_Rel* rel,
+ rtems_rtl_obj_sect_t* sect,
+ const Elf_Sym* sym,
+ const char* symname)
+{
+ printf ("rtl: rel type record not supported; please report\n");
+ return false;
+}
diff --git a/rtl-mdreloc-sparc.c b/rtl-mdreloc-sparc.c
new file mode 100644
index 0000000..4c2b861
--- /dev/null
+++ b/rtl-mdreloc-sparc.c
@@ -0,0 +1,256 @@
+/*
+ * Taken from NetBSD and stripped of the relocations not needed on RTEMS.
+ *
+ * $Id$
+ */
+
+/* $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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include <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 int 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 */
+};
+
+#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 (rtems_rtl_obj_t* obj,
+ const Elf_Rela* rela,
+ rtems_rtl_obj_sect_t* sect,
+ 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", obj->oname, (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",
+ obj->oname, 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;
+ }
+
+ 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/rtl-obj-cache.c b/rtl-obj-cache.c
new file mode 100644
index 0000000..fbe550b
--- /dev/null
+++ b/rtl-obj-cache.c
@@ -0,0 +1,178 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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 <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->offset = 0;
+ cache->size = size;
+ cache->level = 0;
+ cache->buffer = malloc (size);
+ 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)
+{
+ free (cache->buffer);
+ cache->fd = -1;
+ cache->level = 0;
+}
+
+void
+rtems_rtl_obj_cache_flush (rtems_rtl_obj_cache_t* cache)
+{
+ cache->fd = -1;
+ 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)
+{
+ if (*length > cache->size)
+ {
+ rtems_rtl_set_error (EINVAL, "read size larger than cache size");
+ return false;
+ }
+
+ 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;
+ else if (cache->level < cache->size)
+ {
+ /*
+ * This is the remaining data in the file.
+ */
+ *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;
+ }
+
+ 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/rtl-obj-cache.h b/rtl-obj-cache.h
new file mode 100644
index 0000000..014cfd7
--- /dev/null
+++ b/rtl-obj-cache.h
@@ -0,0 +1,131 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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. */
+ 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 fs The file descriptor. Must be an open file.
+ * @param offset The offset in the file to reference the data to.
+ * @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 fs The file descriptor. Must be an open file.
+ * @param offset The offset in the file to read the data from.
+ * @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/rtl-obj-fwd.h b/rtl-obj-fwd.h
new file mode 100644
index 0000000..9f1e757
--- /dev/null
+++ b/rtl-obj-fwd.h
@@ -0,0 +1,41 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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/rtl-obj.c b/rtl-obj.c
new file mode 100644
index 0000000..ef2a894
--- /dev/null
+++ b/rtl-obj.c
@@ -0,0 +1,1040 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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 <rtl.h>
+#include <rtl-chain-iterator.h>
+#include <rtl-obj.h>
+#include "rtl-error.h"
+#include "rtl-trace.h"
+
+rtems_rtl_obj_t*
+rtems_rtl_obj_alloc (void)
+{
+ rtems_rtl_obj_t* obj = malloc (sizeof (rtems_rtl_obj_t));
+ if (obj)
+ {
+ /*
+ * Initalise to 0.
+ */
+ *obj = (rtems_rtl_obj_t) { { 0 } };
+
+ /*
+ * Initialise the chains.
+ */
+ rtems_chain_initialize_empty (&obj->sections);
+ }
+ return obj;
+}
+
+static void
+rtems_rtl_obj_free_names (rtems_rtl_obj_t* obj)
+{
+ free ((void*) obj->oname);
+ free ((void*) obj->aname);
+ if ((obj->fname != obj->aname) && (obj->fname != obj->oname))
+ free ((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_obj_symbol_erase (obj);
+ if (obj->text_base)
+ free (obj->text_base);
+ rtems_rtl_obj_free_names (obj);
+ free (obj);
+ return true;
+}
+
+bool
+rtems_rtl_obj_unresolved (rtems_rtl_obj_t* obj)
+{
+ return (obj->flags & RTEMS_RTL_OBJ_UNRESOLVED) != 0 ? true : false;
+}
+
+static bool
+rtems_rtl_obj_parse_name (rtems_rtl_obj_t* obj, const char* name)
+{
+ const char* p;
+ const char* e;
+ char* aname;
+ char* oname;
+
+ /*
+ * Parse the name to determine if the object file is part of an archive or it
+ * is an object file.
+ */
+ e = name + strlen (name);
+
+ p = strchr (name, ':');
+
+ if (p == NULL)
+ p = e;
+
+ aname = NULL;
+
+ oname = malloc (p - name + 1);
+ if (oname == NULL)
+ {
+ rtems_rtl_set_error (ENOMEM, "no memory for object file name");
+ return false;
+ }
+
+ memcpy (oname, name, p - name);
+ oname[p - name] = '\0';
+
+ if (p != e)
+ {
+ const char* o;
+
+ /*
+ * The file name is an archive and the object file name is next after the
+ * delimiter.
+ */
+ aname = oname;
+ ++p;
+
+ /*
+ * See if there is a '@' to delimit an archive offset for the object in the
+ * archive.
+ */
+ o = strchr (p, '@');
+
+ if (o == NULL)
+ o = e;
+
+ oname = malloc (o - p + 1);
+ if (oname == NULL)
+ {
+ free (aname);
+ rtems_rtl_set_error (ENOMEM, "no memory for object file name");
+ return false;
+ }
+
+ memcpy (oname, p, o - p);
+ oname[o - p] = '\0';
+
+ if (o != e)
+ {
+ /*
+ * The object name has an archive offset. If the number
+ * does not parse 0 will be returned and the archive will be
+ * searched.
+ */
+ obj->ooffset = strtoul (o + 1, 0, 0);
+ }
+ }
+
+ obj->oname = oname;
+ obj->aname = aname;
+
+ return true;
+}
+
+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)
+{
+ struct stat sb;
+ const char* n;
+
+ /*
+ * 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 (obj->aname != NULL)
+ n = obj->aname;
+ else
+ n = obj->oname;
+
+ if (rtems_filesystem_is_separator (n[0]))
+ {
+ if (stat (n, &sb) == 0)
+ obj->fname = n;
+ }
+ else
+ {
+ rtems_rtl_data_t* rtl;
+ const char* s;
+ const char* e;
+ int l;
+
+ rtl = rtems_rtl_lock ();
+
+ s = rtl->paths;
+ e = s + strlen (rtl->paths);
+ l = strlen (n);
+
+ while ((obj->fname == NULL) && (s != e))
+ {
+ const char* d;
+ char* p;
+
+ d = strchr (s, ':');
+ if (d == NULL)
+ d = e;
+
+ /*
+ * Allocate the path fragment, separator, name, terminating nul.
+ */
+ p = malloc ((d - s) + 1 + l + 1);
+ if (p == NULL)
+ {
+ rtems_rtl_set_error (ENOMEM, "no memory searching for object file");
+ rtems_rtl_unlock ();
+ return false;
+ }
+
+ memcpy (p, s, d - s);
+ p[d - s] = '/';
+ memcpy (p + (d - s) + 1, n, l);
+ p[(d - s) + 1 + l] = '\0';
+
+ if (stat (p, &sb) < 0)
+ free (p);
+ else
+ {
+ /*
+ * We have found the file. Do not release the path memory.
+ */
+ obj->fname = p;
+ }
+
+ s = d;
+ }
+
+ rtems_rtl_unlock ();
+ }
+
+ if (obj->fname)
+ obj->fsize = sb.st_size;
+ else
+ rtems_rtl_set_error (ENOMEM, "object file not found");
+
+ return obj->fname ? true : false;
+}
+
+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 = malloc (sizeof (rtems_rtl_obj_sect_t));
+ if (!sect)
+ {
+ rtems_rtl_set_error (ENOMEM, "adding allocated section");
+ return false;
+ }
+ sect->section = section;
+ sect->name = 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 ("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);
+ free ((void*) sect->name);
+ free (node);
+ 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 (rtems_chain_control* sections,
+ uint32_t mask,
+ int fd,
+ off_t offset,
+ uint8_t* base)
+{
+ 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))
+ {
+ uint8_t* sect_base = base + base_offset;
+
+ if (!first)
+ base_offset = rtems_rtl_sect_align (base_offset, sect->alignment);
+
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
+ printf ("rtl: loading: %s -> %8p (%zi)\n",
+ sect->name, base + base_offset, sect->size);
+
+ if ((sect->flags & RTEMS_RTL_OBJ_SECT_LOAD) == RTEMS_RTL_OBJ_SECT_LOAD)
+ {
+ size_t len;
+
+ if (lseek (fd, offset + sect->offset, SEEK_SET) < 0)
+ {
+ rtems_rtl_set_error (errno, "section load seek failed");
+ return false;
+ }
+
+ len = sect->size;
+ while (len)
+ {
+ ssize_t r = read (fd, base + base_offset, len);
+ if (r <= 0)
+ {
+ rtems_rtl_set_error (errno, "section load read failed");
+ return false;
+ }
+ base_offset += r;
+ len -= r;
+ }
+ }
+ else if ((sect->flags & RTEMS_RTL_OBJ_SECT_ZERO) == RTEMS_RTL_OBJ_SECT_ZERO)
+ {
+ memset (base + base_offset, 0, sect->size);
+ base_offset += sect->size;
+ }
+ else
+ {
+ rtems_rtl_set_error (errno, "section has no load op");
+ return false;
+ }
+
+ sect->base = sect_base;
+ first = false;
+ }
+
+ node = rtems_chain_next (node);
+ }
+
+ return true;
+}
+
+bool
+rtems_rtl_obj_load_sections (rtems_rtl_obj_t* obj, int fd)
+{
+ 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);
+
+ /*
+ * The object file's memory allocated on the heap. This should be the
+ * first allocation and any temporary allocations come after this
+ * so the heap does not become fragmented.
+ */
+ obj->exec_size = text_size + const_size + data_size + bss_size;
+ obj->text_base = malloc (obj->exec_size);
+ if (!obj->text_base)
+ {
+ obj->exec_size = 0;
+ rtems_rtl_set_error (ENOMEM, "no memory to load obj");
+ return false;
+ }
+
+ obj->const_base = obj->text_base + text_size;
+ obj->data_base = obj->const_base + const_size;
+ obj->bss_base = obj->data_base + data_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 (&obj->sections, RTEMS_RTL_OBJ_SECT_TEXT,
+ fd, obj->ooffset, obj->text_base) ||
+ !rtems_rtl_obj_sections_loader (&obj->sections, RTEMS_RTL_OBJ_SECT_CONST,
+ fd, obj->ooffset, obj->const_base) ||
+ !rtems_rtl_obj_sections_loader (&obj->sections, RTEMS_RTL_OBJ_SECT_DATA,
+ fd, obj->ooffset, obj->data_base) ||
+ !rtems_rtl_obj_sections_loader (&obj->sections, RTEMS_RTL_OBJ_SECT_BSS,
+ fd, obj->ooffset, obj->bss_base))
+ {
+ free (obj->text_base);
+ obj->exec_size = 0;
+ obj->text_base = 0;
+ obj->data_base = 0;
+ obj->bss_base = 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 so
+ */
+ 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_load (rtems_rtl_obj_t* obj)
+{
+ int fd;
+
+ if (!obj->fname)
+ {
+ rtems_rtl_set_error (ENOMEM, "invalid object file name path");
+ return false;
+ }
+
+ fd = open (obj->fname, 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 (obj->aname != NULL)
+ {
+ 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;
+ }
+
+ rtems_rtl_obj_caches_flush ();
+
+ close (fd);
+
+ return true;
+}
+
+bool
+rtems_rtl_obj_unload (rtems_rtl_obj_t* obj)
+{
+ rtems_rtl_obj_symbol_erase (obj);
+ return rtems_rtl_obj_free (obj);
+}
diff --git a/rtl-obj.h b/rtl-obj.h
new file mode 100644
index 0000000..5074056
--- /dev/null
+++ b/rtl-obj.h
@@ -0,0 +1,423 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object Support.
+ */
+
+#if !defined (_RTEMS_RTL_MAP_H_)
+#define _RTEMS_RTL_MAP_H_
+
+#include <rtems.h>
+#include <rtems/chain.h>
+#include <rtl-sym.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * 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. */
+ 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. */
+};
+
+/**
+ * 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);
+
+/**
+ * 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);
+
+/**
+ * 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);
+
+/**
+ * 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.
+ * @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);
+
+/**
+ * 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/rtl-shell.c b/rtl-shell.c
new file mode 100644
index 0000000..fac9509
--- /dev/null
+++ b/rtl-shell.c
@@ -0,0 +1,314 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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 <rtl.h>
+#include <rtl-chain-iterator.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 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;
+}
+
+/**
+ * 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;
+ char flags_str[33];
+
+ /*
+ * Skip the base module unless asked to show it.
+ */
+ if (!print->base && (obj == print->rtl->base))
+ return true;
+
+ printf ("%-*cobject name : %s\n", print->indent, ' ', obj->oname);
+ if (print->names)
+ {
+ printf ("%-*cfile name : %s\n", print->indent, ' ', obj->fname);
+ printf ("%-*carchive name : %s\n", print->indent, ' ', obj->aname);
+ 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);
+ }
+ printf ("%-*cexec size : %zi\n", print->indent, ' ', obj->exec_size);
+ if (print->memory_map)
+ {
+ 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 ("%-*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);
+ }
+ return true;
+}
+
+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.names = true;
+ print.memory_map = true;
+ print.symbols = true;
+ 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[])
+{
+ return 0;
+}
+
+static int
+rtems_rtl_shell_object (rtems_rtl_data_t* rtl, int argc, char *argv[])
+{
+ return 0;
+}
+
+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/rtl-shell.h b/rtl-shell.h
new file mode 100644
index 0000000..93b5640
--- /dev/null
+++ b/rtl-shell.h
@@ -0,0 +1,41 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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/rtl-sym.c b/rtl-sym.c
new file mode 100644
index 0000000..dc94e24
--- /dev/null
+++ b/rtl-sym.c
@@ -0,0 +1,231 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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 <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 = calloc (buckets, sizeof (rtems_chain_control));
+ 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)
+{
+ free (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 = malloc (obj->global_size);
+ 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_obj_symbol_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);
+ free (obj->global_table);
+ obj->global_table = NULL;
+ obj->global_size = 0;
+ obj->global_syms = 0;
+ }
+}
diff --git a/rtl-sym.h b/rtl-sym.h
new file mode 100644
index 0000000..aa7946e
--- /dev/null
+++ b/rtl-sym.h
@@ -0,0 +1,122 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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. */
+} 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);
+
+/**
+ * Erase the object file's symbols.
+ *
+ * @param obj The object file the symbols are to be erased from.
+ */
+void rtems_rtl_obj_symbol_erase (rtems_rtl_obj_t* obj);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/rtl-trace.c b/rtl-trace.c
new file mode 100644
index 0000000..bce9c56
--- /dev/null
+++ b/rtl-trace.c
@@ -0,0 +1,133 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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"
+ };
+
+ 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/rtl-trace.h b/rtl-trace.h
new file mode 100644
index 0000000..1767761
--- /dev/null
+++ b/rtl-trace.h
@@ -0,0 +1,99 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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)
+
+/**
+ * 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/rtl.c b/rtl.c
new file mode 100644
index 0000000..3898827
--- /dev/null
+++ b/rtl.c
@@ -0,0 +1,520 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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 <rtl.h>
+#include "rtl-error.h"
+#include "rtl-trace.h"
+
+/**
+ * Semaphore configuration to create a mutex.
+ */
+#define RTEMS_MUTEX_ATTRIBS \
+ (RTEMS_PRIORITY | RTEMS_BINARY_SEMAPHORE | \
+ RTEMS_NO_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)
+
+/**
+ * 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;
+
+ rtl = malloc (sizeof (rtems_rtl_data_t));
+ if (!rtl)
+ {
+ errno = ENOMEM;
+ return false;
+ }
+
+ *rtl = (rtems_rtl_data_t) { 0 };
+
+ rtems_chain_initialize_empty (&rtl->objects);
+
+ rtl->base = rtems_rtl_obj_alloc ();
+ if (!rtl->base)
+ {
+ free (rtl);
+ return false;
+ }
+
+ /*
+ * Need to malloc the memory so the free does not complain.
+ */
+ rtl->base->oname = strdup ("rtems-kernel");
+
+ rtems_chain_append (&rtl->objects, &rtl->base->link);
+
+ if (!rtems_rtl_symbol_table_open (&rtl->globals,
+ RTEMS_RTL_SYMS_GLOBAL_BUCKETS))
+ {
+ rtems_rtl_obj_free (rtl->base);
+ 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_obj_free (rtl->base);
+ 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_symbol_table_close (&rtl->globals);
+ rtems_rtl_obj_free (rtl->base);
+ 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_symbol_table_close (&rtl->globals);
+ rtems_rtl_obj_free (rtl->base);
+ free (rtl);
+ return false;
+ }
+
+ sc = rtems_semaphore_create(rtems_build_name ('R', 'T', 'L', 'D'),
+ 1, RTEMS_MUTEX_ATTRIBS,
+ RTEMS_NO_PRIORITY, &rtl->lock);
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ rtems_rtl_obj_cache_close (&rtl->relocs);
+ rtems_rtl_obj_cache_close (&rtl->strings);
+ rtems_rtl_obj_cache_close (&rtl->symbols);
+ rtems_rtl_symbol_table_close (&rtl->globals);
+ rtems_rtl_obj_free (rtl->base);
+ free (rtl);
+ return false;
+ }
+ }
+
+ rtems_libio_unlock ();
+
+ rtems_rtl_path_append (".");
+
+ rtems_rtl_base_global_syms_init ();
+ }
+ return true;
+}
+
+rtems_rtl_data_t*
+rtems_rtl_data (void)
+{
+ return rtl;
+}
+
+rtems_rtl_symbols_t*
+rtems_rtl_global_symbols (void)
+{
+ if (!rtl)
+ return NULL;
+ return &rtl->globals;
+}
+
+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);
+ }
+}
+
+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;
+
+ 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 (rtems_rtl_match_name (obj, name))
+ return obj;
+ node = rtems_chain_next (node);
+ }
+
+ return NULL;
+}
+
+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;
+ }
+ }
+
+ /*
+ * Increase the number of users.
+ */
+ ++obj->users;
+
+ /*
+ * 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", obj->fname);
+
+ /*
+ * 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 = malloc (len + 1);
+
+ 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/rtl.h b/rtl.h
new file mode 100644
index 0000000..d9f9356
--- /dev/null
+++ b/rtl.h
@@ -0,0 +1,273 @@
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@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.
+ *
+ * $Id$
+ */
+/**
+ * @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-elf.h>
+#include <rtl-fwd.h>
+#include <rtl-elf.h>
+#include <rtl-obj.h>
+#include <rtl-obj-cache.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'.
+ */
+
+/**
+ * The number of buckets in the global symbol table.
+ */
+#define RTEMS_RTL_SYMS_GLOBAL_BUCKETS (32)
+
+/**
+ * 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_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_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. */
+ 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 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);
+
+/**
+ * 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 ELF 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 ELF format file in that specific
+ * location on the file system.
+ * 2. Relative file references an ELF 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.
+ *
+ * @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/rtld-gsyms.c b/rtld-gsyms.c
new file mode 100644
index 0000000..171818a
--- /dev/null
+++ b/rtld-gsyms.c
@@ -0,0 +1 @@
+#include "gsyms.c"
diff --git a/shell-init b/shell-init
new file mode 100644
index 0000000..06a6cb7
--- /dev/null
+++ b/shell-init
@@ -0,0 +1,3 @@
+#rtl-trace set all
+#rtl-trace set load load-sect reloc
+#dlo libx.a:x-long-name-to-create-gnu-extension-in-archive.o
diff --git a/sys/mman.h b/sys/mman.h
new file mode 100644
index 0000000..8c816a6
--- /dev/null
+++ b/sys/mman.h
@@ -0,0 +1,185 @@
+/* $NetBSD: mman.h,v 1.36 2005/09/13 01:42:51 christos Exp $ */
+
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)mman.h 8.2 (Berkeley) 1/9/95
+ */
+
+#ifndef _SYS_MMAN_H_
+#define _SYS_MMAN_H_
+
+#ifdef __rtems__
+
+#include <inttypes.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+#else /* __rtems__ */
+#include <sys/featuretest.h>
+
+#include <machine/ansi.h>
+
+#ifdef _BSD_SIZE_T_
+typedef _BSD_SIZE_T_ size_t;
+#undef _BSD_SIZE_T_
+#endif
+
+#include <sys/ansi.h>
+
+#ifndef mode_t
+typedef __mode_t mode_t;
+#define mode_t __mode_t
+#endif
+
+#ifndef off_t
+typedef __off_t off_t; /* file offset */
+#define off_t __off_t
+#endif
+#endif /* __rtems__ */
+
+
+/*
+ * Protections are chosen from these bits, or-ed together
+ */
+#define PROT_NONE 0x00 /* no permissions */
+#define PROT_READ 0x01 /* pages can be read */
+#define PROT_WRITE 0x02 /* pages can be written */
+#define PROT_EXEC 0x04 /* pages can be executed */
+
+/*
+ * Flags contain sharing type and options.
+ * Sharing types; choose one.
+ */
+#define MAP_SHARED 0x0001 /* share changes */
+#define MAP_PRIVATE 0x0002 /* changes are private */
+
+#ifdef _KERNEL
+/*
+ * Deprecated flag; these are treated as MAP_PRIVATE internally by
+ * the kernel.
+ */
+#define MAP_COPY 0x0004 /* "copy" region at mmap time */
+#endif
+
+/*
+ * Other flags
+ */
+#define MAP_FIXED 0x0010 /* map addr must be exactly as requested */
+#define MAP_RENAME 0x0020 /* Sun: rename private pages to file */
+#define MAP_NORESERVE 0x0040 /* Sun: don't reserve needed swap area */
+#define MAP_INHERIT 0x0080 /* region is retained after exec */
+#define MAP_HASSEMAPHORE 0x0200 /* region may contain semaphores */
+#define MAP_TRYFIXED 0x0400 /* attempt hint address, even within break */
+#define MAP_WIRED 0x0800 /* mlock() mapping when it is established */
+
+/*
+ * Mapping type
+ */
+#define MAP_FILE 0x0000 /* map from file (default) */
+#define MAP_ANON 0x1000 /* allocated from memory, swap space */
+
+/*
+ * Alignment (expressed in log2). Must be >= log2(PAGE_SIZE) and
+ * < # bits in a pointer (26 (acorn26), 32 or 64).
+ */
+#define MAP_ALIGNED(n) ((n) << MAP_ALIGNMENT_SHIFT)
+#define MAP_ALIGNMENT_SHIFT 24
+#define MAP_ALIGNMENT_MASK MAP_ALIGNED(0xff)
+#define MAP_ALIGNMENT_64KB MAP_ALIGNED(16) /* 2^16 */
+#define MAP_ALIGNMENT_16MB MAP_ALIGNED(24) /* 2^24 */
+#define MAP_ALIGNMENT_4GB MAP_ALIGNED(32) /* 2^32 */
+#define MAP_ALIGNMENT_1TB MAP_ALIGNED(40) /* 2^40 */
+#define MAP_ALIGNMENT_256TB MAP_ALIGNED(48) /* 2^48 */
+#define MAP_ALIGNMENT_64PB MAP_ALIGNED(56) /* 2^56 */
+
+/*
+ * Error indicator returned by mmap(2)
+ */
+#define MAP_FAILED ((void *) -1) /* mmap() failed */
+
+/*
+ * Flags to msync
+ */
+#define MS_ASYNC 0x01 /* perform asynchronous writes */
+#define MS_INVALIDATE 0x02 /* invalidate cached data */
+#define MS_SYNC 0x04 /* perform synchronous writes */
+
+/*
+ * Flags to mlockall
+ */
+#define MCL_CURRENT 0x01 /* lock all pages currently mapped */
+#define MCL_FUTURE 0x02 /* lock all pages mapped in the future */
+
+#if defined(_NETBSD_SOURCE)
+/*
+ * Advice to madvise
+ */
+#define MADV_NORMAL 0 /* no further special treatment */
+#define MADV_RANDOM 1 /* expect random page references */
+#define MADV_SEQUENTIAL 2 /* expect sequential page references */
+#define MADV_WILLNEED 3 /* will need these pages */
+#define MADV_DONTNEED 4 /* dont need these pages */
+#define MADV_SPACEAVAIL 5 /* insure that resources are reserved */
+#define MADV_FREE 6 /* pages are empty, free them */
+/*
+ * Flags to minherit
+ */
+#define MAP_INHERIT_SHARE 0 /* share with child */
+#define MAP_INHERIT_COPY 1 /* copy into child */
+#define MAP_INHERIT_NONE 2 /* absent from child */
+#define MAP_INHERIT_DONATE_COPY 3 /* copy and delete -- not
+ implemented in UVM */
+#define MAP_INHERIT_DEFAULT MAP_INHERIT_COPY
+#endif
+
+#ifndef _KERNEL
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+void *mmap(void *, size_t, int, int, int, off_t);
+int munmap(void *, size_t);
+int mprotect(void *, size_t, int);
+#ifndef __LIBC12_SOURCE__
+int msync(void *, size_t, int) __RENAME(__msync13);
+#endif
+int mlock(const void *, size_t);
+int munlock(const void *, size_t);
+int mlockall(int);
+int munlockall(void);
+#if defined(_NETBSD_SOURCE)
+int madvise(void *, size_t, int);
+int mincore(void *, size_t, char *);
+int minherit(void *, size_t, int);
+#endif
+__END_DECLS
+
+#endif /* !_KERNEL */
+
+#endif /* !_SYS_MMAN_H_ */
diff --git a/wscript b/wscript
new file mode 100644
index 0000000..fb85ada
--- /dev/null
+++ b/wscript
@@ -0,0 +1,142 @@
+#
+# Waf build script for the Run Time Link editor development project.
+#
+import rtems
+
+version = "1.0.0"
+
+def init(ctx):
+ rtems.init(ctx)
+
+def options(opt):
+ rtems.options(opt)
+
+def configure(conf):
+ rtems.configure(conf)
+
+ conf.env.ASCIIDOC = conf.find_program(['asciidoc.py'], mandatory = False)
+ conf.env.ASCIIDOC_FLAGS = ['-b', 'html5', '-a', 'data-uri', '-a', 'icons', '-a', 'max-width=55em-a']
+
+def build(bld):
+ bld.add_post_fun(rtl_post_build)
+
+ rtems.build(bld)
+
+ arch = bld.get_env()['RTEMS_ARCH']
+
+ bld.includes = ['.',
+ 'libbsd/include',
+ 'libbsd/include/arch/' + arch]
+
+ rtl_source(bld, arch)
+ rtl_liba(bld, arch)
+ rtl_root_fs(bld)
+ rtl_gsyms(bld)
+
+ bld(target = 'rtld',
+ features = 'c cprogram',
+ source = ['init.c',
+ 'main.c',
+ 'fs-root-tarfile.o'],
+ includes = bld.includes,
+ defines = ['PACKAGE_VERSION="' + version + '"'],
+ use = ['rtl', 'rootfs', 'rtld-gsyms'],
+ depends_on = 'gsyms')
+
+ if bld.env.ASCIIDOC:
+ bld(target = 'rtems-rtl.html', source = 'rtems-rtl.txt')
+
+def rtl_source(bld, arch):
+ bld(target = 'rtl',
+ features = 'c',
+ includes = bld.includes,
+ source = ['dlfcn.c',
+ 'dlfcn-shell.c',
+ 'rtl.c',
+ 'rtl-chain-iterator.c',
+ 'rtl-debugger.c',
+ 'rtl-elf.c',
+ 'rtl-error.c',
+ 'rtl-obj.c',
+ 'rtl-obj-cache.c',
+ 'rtl-shell.c',
+ 'rtl-sym.c',
+ 'rtl-trace.c',
+ 'rtl-mdreloc-' + arch + '.c'])
+
+def rtl_liba(bld, arch):
+ bld(target = 'x',
+ features = 'c cstlib',
+ includes = bld.includes,
+ source = ['xa.c',
+ 'x-long-name-to-create-gnu-extension-in-archive.c'])
+
+def mmap_source(bld, includes):
+ bld(target = 'mmap',
+ features = 'c',
+ includes = includes,
+ source = ['mmap.c',
+ 'munmap.c'])
+
+def rtl_root_fs(bld):
+ bld(target = 'fs-root.tar',
+ source = ['shell-init', 'libx.a', 'a.out'],
+ rule = 'tar cf - ${SRC} > ${TGT}')
+ bld.objects(name = 'rootfs',
+ target = 'fs-root-tarfile.o',
+ source = 'fs-root.tar',
+ rule = '${OBJCOPY} -I binary -B ${RTEMS_ARCH} ${OBJCOPY_FLAGS} ${SRC} ${TGT}')
+
+def rtl_pre_build(bld):
+ pass
+
+def rtl_post_build(bld):
+ rtl_gsyms(bld)
+
+def rtl_gsyms(bld):
+ import os.path
+ src = os.path.join(bld.get_variant_dir(), 'gsyms.c')
+ if os.path.exists(src):
+ if os.path.exists(os.path.join(bld.get_variant_dir(), 'rtld')):
+ import os
+ sb = os.stat(src)
+ if sb.st_size == 0:
+ bld(name = 'gsyms',
+ target = 'gsyms.c',
+ always = True,
+ rule = '${NM} -g rtld | awk -f ../../mksyms.awk - > ${TGT}')
+ else:
+ open(src, 'a').close()
+ bld(target = 'rtld-gsyms',
+ features = 'c',
+ includes = bld.includes,
+ source = ['rtld-gsyms.c'],
+ depends_on = 'gsyms')
+
+def x_rtl_gsyms(bld):
+ import os.path
+ src = os.path.join(bld.get_variant_dir(), 'gsyms.c')
+ if os.path.exists(src):
+ if os.path.exists(os.path.join(bld.get_variant_dir(), 'rtld')):
+ import os
+ sb = os.stat(src)
+ if sb.st_size == 0:
+ bld(name = 'gsyms',
+ target = 'gsyms.c',
+ always = True,
+ rule = '${NM} -g rtld | awk -f ../../mksyms.awk - > ${TGT}')
+ else:
+ open(src, 'a').close()
+ bld(target = 'rtld-gsyms',
+ features = 'c',
+ includes = bld.includes,
+ source = ['rtld-gsyms.c'],
+ depends_on = 'gsyms')
+
+import TaskGen
+TaskGen.declare_chain(name = 'html',
+ rule = '${ASCIIDOC} ${ASCIIDOC_FLAGS} -o ${TGT} ${SRC}',
+ shell = False,
+ ext_in = '.txt',
+ ext_out = '.html',
+ reentrant = False)
diff --git a/x-long-name-to-create-gnu-extension-in-archive.c b/x-long-name-to-create-gnu-extension-in-archive.c
new file mode 100644
index 0000000..55d614a
--- /dev/null
+++ b/x-long-name-to-create-gnu-extension-in-archive.c
@@ -0,0 +1,44 @@
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include "x.h"
+
+static int zero;
+unsigned int public = 0x12345678;
+
+void x_writeln(const char* s);
+void y_writeln(const char* s) __attribute__ ((section (".bar")));
+
+void
+w_writeln(double d)
+{
+ printf ("sin(%f) = %f\n", d, sin(d));
+}
+
+void
+x_writeln(const char* s)
+{
+ printf ("%s\n", s);
+}
+
+void y_writeln(const char* s)
+{
+ x_writeln (s);
+}
+
+int z_writeln(int argc, const char* argv[])
+{
+ int arg;
+ printf ("public = 0x%08x, zero = %d\n", public, ++zero);
+ for (arg = 0; arg < argc; ++arg)
+ y_writeln (argv[arg]);
+ return 123;
+}
+
+int
+my_main (int argc, char* argv[])
+{
+ exit (0);
+}
diff --git a/x.h b/x.h
new file mode 100644
index 0000000..2e3ffcf
--- /dev/null
+++ b/x.h
@@ -0,0 +1,7 @@
+
+#ifndef _X_H_
+#define _X_H_
+
+void x_writeln (const char* s);
+
+#endif
diff --git a/xa.c b/xa.c
new file mode 100644
index 0000000..f402449
--- /dev/null
+++ b/xa.c
@@ -0,0 +1,9 @@
+
+
+#include "x.h"
+
+void
+hello (void)
+{
+ x_writeln ("hello world");
+}